Add --help option.
authorNick Clifton <nickc@cygnus.com>
Mon, 13 Jul 1998 17:20:29 +0000 (17:20 +0000)
committerNick Clifton <nickc@gcc.gnu.org>
Mon, 13 Jul 1998 17:20:29 +0000 (17:20 +0000)
From-SVN: r21109

gcc/ChangeLog
gcc/cccp.c
gcc/cpplib.c
gcc/gcc.c
gcc/tm.texi
gcc/toplev.c

index 5904eb6..a64917e 100644 (file)
@@ -1,3 +1,22 @@
+Mon Jul 13 17:18:47 1998  Nick Clifton  <nickc@cygnus.com>
+
+       * cccp.c (main): Add support for parsing --help.
+       (display_help): New function: display command line switches.
+
+       * cpplib.c (cpp_handle_option): Add support for parsing --help.
+       (display_help): New function: display command line switches.
+
+       * gcc.c (main): Add support for parsing --help, and passing it on
+       to the sub-processes invoked by gcc.
+       (display_help): New function: display comman line switches.     
+
+       * tm.texi (TARGET_SWITCHES and TARGET_OPTIONS): Document
+       'description' field added to structure.  
+
+       * toplev.c: Add support for parsing --help.
+       Add documentation strings to command line option tables.
+       (display_help): New function: display comman line switches.
+
 Mon Jul 13 16:15:10 1998  John Carr  <jfc@mit.edu>
 
        * sparc.c, sparc.h, sparc.md: New trampoline code.
index d717009..1bd7649 100644 (file)
@@ -1047,6 +1047,7 @@ GENERIC_PTR xmalloc PROTO((size_t));
 static GENERIC_PTR xrealloc PROTO((GENERIC_PTR, size_t));
 static GENERIC_PTR xcalloc PROTO((size_t, size_t));
 static char *savestring PROTO((char *));
+static void print_help PROTO((void));
 \f
 /* Read LEN bytes at PTR from descriptor DESC, for file FILENAME,
    retrying if necessary.  If MAX_READ_LEN is defined, read at most
@@ -1146,6 +1147,73 @@ eprint_string (string, length)
 }
 
 \f
+static void
+print_help ()
+{
+  printf ("Usage: %s [switches] input output\n", progname);
+  printf ("Switches:\n");
+  printf ("  -include <file>           Include the contents of <file> before other files\n");
+  printf ("  -imacros <file>           Accept definition of marcos in <file>\n");
+  printf ("  -iprefix <path>           Specify <path> as a prefix for next two options\n");
+  printf ("  -iwithprefix <dir>        Add <dir> to the end of the system include paths\n");
+  printf ("  -iwithprefixbefore <dir>  Add <dir> to the end of the main include paths\n");
+  printf ("  -isystem <dir>            Add <dir> to the start of the system include paths\n");
+  printf ("  -idirafter <dir>          Add <dir> to the end of the system include paths\n");
+  printf ("  -I <dir>                  Add <dir> to the end of the main include paths\n");
+  printf ("  -nostdinc                 Do not search the system include directories\n");
+  printf ("  -nostdinc++               Do not search the system include directories for C++\n");
+  printf ("  -o <file>                 Put output into <file>\n");
+  printf ("  -pedantic                 Issue all warnings demanded by strict ANSI C\n");
+  printf ("  -traditional              Follow K&R pre-processor behaviour\n");
+  printf ("  -trigraphs                Support ANSI C trigraphs\n");
+  printf ("  -lang-c                   Assume that the input sources are in C\n");
+  printf ("  -lang-c89                 Assume that the input sources are in C89\n");
+  printf ("  -lang-c++                 Assume that the input sources are in C++\n");
+  printf ("  -lang-objc                Assume that the input sources are in ObjectiveC\n");
+  printf ("  -lang-objc++              Assume that the input sources are in ObjectiveC++\n");
+  printf ("  -lang-asm                 Assume that the input sources are in assembler\n");
+  printf ("  -lang-chill               Assume that the input sources are in Chill\n");
+  printf ("  -+                        Allow parsing of C++ style features\n");
+  printf ("  -w                        Inhibit warning messages\n");
+  printf ("  -Wtrigraphs               Warn if trigraphs are encountered\n");
+  printf ("  -Wno-trigraphs            Do not warn about trigraphs\n");
+  printf ("  -Wcomment{s}              Warn if one comment starts inside another\n");
+  printf ("  -Wno-comment{s}           Do not warn about comments\n");
+  printf ("  -Wtraditional             Warn if a macro argument is/would be turned into\n");
+  printf ("                             a string if -tradtional is specified\n");
+  printf ("  -Wno-traditional          Do not warn about stringification\n");
+  printf ("  -Wundef                   Warn if an undefined macro is used by #if\n");
+  printf ("  -Wno-undef                Do not warn about testing udefined macros\n");
+  printf ("  -Wimport                  Warn about the use of the #import directive\n");
+  printf ("  -Wno-import               Do not warn about the use of #import\n");
+  printf ("  -Werror                   Treat all warnings as errors\n");
+  printf ("  -Wno-error                Do not treat warnings as errors\n");
+  printf ("  -Wall                     Enable all preprocessor warnings\n");
+  printf ("  -M                        Generate make dependencies\n");
+  printf ("  -MM                       As -M, but ignore system header files\n");
+  printf ("  -MD                       As -M, but put output in a .d file\n");
+  printf ("  -MMD                      As -MD, but ignore system header files\n");
+  printf ("  -MG                       Treat missing header file as generated files\n");
+  printf ("  -g                        Include #define and #undef directives in the output\n");
+  printf ("  -D<macro>                 Define a <macro> with string '1' as its value\n");
+  printf ("  -D<macro>=<val>           Define a <macro> with <val> as its value\n");
+  printf ("  -A<question> (<answer>)   Assert the <answer> to <question>\n");
+  printf ("  -U<macro>                 Undefine <macro> \n");
+  printf ("  -u or -undef              Do not predefine any macros\n");
+  printf ("  -v                        Display the version number\n");
+  printf ("  -H                        Print the name of header files as they are used\n");
+  printf ("  -C                        Do not discard comments\n");
+  printf ("  -dM                       Display a list of macro definitions active at end\n");
+  printf ("  -dD                       Preserve macro definitions in output\n");
+  printf ("  -dN                       As -dD except that only the names are preserved\n");
+  printf ("  -dI                       Include #include directives in the output\n");
+  printf ("  -ifoutput                 Describe skipped code blocks in output \n");
+  printf ("  -P                        Do not generate #line directives\n");
+  printf ("  -$                        Do not include '$' in identifiers\n");
+  printf ("  -remap                    Remap file names when including files.\n");
+  printf ("  -h or --help              Display this information\n");
+}
+\f
 int
 main (argc, argv)
      int argc;
@@ -1245,7 +1313,10 @@ main (argc, argv)
   for (i = 1; i < argc; i++) {
     if (argv[i][0] != '-') {
       if (out_fname != NULL)
-       fatal ("Usage: %s [switches] input output", argv[0]);
+       {
+         print_help ();
+         fatal ("Too many arguments");
+       }
       else if (in_fname != NULL)
        out_fname = argv[i];
       else
@@ -1525,6 +1596,13 @@ main (argc, argv)
          debug_output = 1;
        break;
 
+      case '-':
+       if (strcmp (argv[i], "--help") != 0)
+         return i;
+       print_help ();
+       exit (0);
+       break;
+
       case 'v':
        fprintf (stderr, "GNU CPP version %s", version_string);
 #ifdef TARGET_VERSION
index 095d559..c988097 100644 (file)
@@ -251,7 +251,8 @@ static char *savestring                     PROTO ((char *));
 static void conditional_skip           PROTO ((cpp_reader *, int,
                                               enum node_type, U_CHAR *));
 static void skip_if_group              PROTO ((cpp_reader *, int));
-static int parse_name PARAMS ((cpp_reader *, int));
+static int parse_name                   PARAMS ((cpp_reader *, int));
+static void print_help                  PROTO ((void));
 
 /* Last arg to output_line_command.  */
 enum file_change_code {same_file, enter_file, leave_file};
@@ -6235,6 +6236,79 @@ push_pending (pfile, cmd, arg)
   CPP_OPTIONS (pfile)->pending = pend;
 }
 
+\f
+static void
+print_help ()
+{
+  printf ("Usage: %s [switches] input output\n", progname);
+  printf ("Switches:\n");
+  /* start-sanitize-obscured-headers */
+  printf ("  -fgenobscured=<args>      Generate obscured versions of header files used\n");
+  printf ("  -fuseobscured=<args>      Search for obscured versions of header files\n");
+  /* end-sanitize-obscured-headers */
+  printf ("  -include <file>           Include the contents of <file> before other files\n");
+  printf ("  -imacros <file>           Accept definition of marcos in <file>\n");
+  printf ("  -iprefix <path>           Specify <path> as a prefix for next two options\n");
+  printf ("  -iwithprefix <dir>        Add <dir> to the end of the system include paths\n");
+  printf ("  -iwithprefixbefore <dir>  Add <dir> to the end of the main include paths\n");
+  printf ("  -isystem <dir>            Add <dir> to the start of the system include paths\n");
+  printf ("  -idirafter <dir>          Add <dir> to the end of the system include paths\n");
+  printf ("  -I <dir>                  Add <dir> to the end of the main include paths\n");
+  printf ("  -nostdinc                 Do not search the system include directories\n");
+  printf ("  -nostdinc++               Do not search the system include directories for C++\n");
+  printf ("  -o <file>                 Put output into <file>\n");
+  printf ("  -pedantic                 Issue all warnings demanded by strict ANSI C\n");
+  printf ("  -traditional              Follow K&R pre-processor behaviour\n");
+  printf ("  -trigraphs                Support ANSI C trigraphs\n");
+  printf ("  -lang-c                   Assume that the input sources are in C\n");
+  printf ("  -lang-c89                 Assume that the input sources are in C89\n");
+  printf ("  -lang-c++                 Assume that the input sources are in C++\n");
+  printf ("  -lang-objc                Assume that the input sources are in ObjectiveC\n");
+  printf ("  -lang-objc++              Assume that the input sources are in ObjectiveC++\n");
+  printf ("  -lang-asm                 Assume that the input sources are in assembler\n");
+  printf ("  -lang-chill               Assume that the input sources are in Chill\n");
+  printf ("  -+                        Allow parsing of C++ style features\n");
+  printf ("  -w                        Inhibit warning messages\n");
+  printf ("  -Wtrigraphs               Warn if trigraphs are encountered\n");
+  printf ("  -Wno-trigraphs            Do not warn about trigraphs\n");
+  printf ("  -Wcomment{s}              Warn if one comment starts inside another\n");
+  printf ("  -Wno-comment{s}           Do not warn about comments\n");
+  printf ("  -Wtraditional             Warn if a macro argument is/would be turned into\n");
+  printf ("                             a string if -tradtional is specified\n");
+  printf ("  -Wno-traditional          Do not warn about stringification\n");
+  printf ("  -Wundef                   Warn if an undefined macro is used by #if\n");
+  printf ("  -Wno-undef                Do not warn about testing udefined macros\n");
+  printf ("  -Wimport                  Warn about the use of the #import directive\n");
+  printf ("  -Wno-import               Do not warn about the use of #import\n");
+  printf ("  -Werror                   Treat all warnings as errors\n");
+  printf ("  -Wno-error                Do not treat warnings as errors\n");
+  printf ("  -Wall                     Enable all preprocessor warnings\n");
+  printf ("  -M                        Generate make dependencies\n");
+  printf ("  -MM                       As -M, but ignore system header files\n");
+  printf ("  -MD                       As -M, but put output in a .d file\n");
+  printf ("  -MMD                      As -MD, but ignore system header files\n");
+  printf ("  -MG                       Treat missing header file as generated files\n");
+  printf ("  -g                        Include #define and #undef directives in the output\n");
+  printf ("  -D<macro>                 Define a <macro> with string '1' as its value\n");
+  printf ("  -D<macro>=<val>           Define a <macro> with <val> as its value\n");
+  printf ("  -A<question> (<answer>)   Assert the <answer> to <question>\n");
+  printf ("  -U<macro>                 Undefine <macro> \n");
+  printf ("  -u or -undef              Do not predefine any macros\n");
+  printf ("  -v                        Display the version number\n");
+  printf ("  -H                        Print the name of header files as they are used\n");
+  printf ("  -C                        Do not discard comments\n");
+  printf ("  -dM                       Display a list of macro definitions active at end\n");
+  printf ("  -dD                       Preserve macro definitions in output\n");
+  printf ("  -dN                       As -dD except that only the names are preserved\n");
+  printf ("  -dI                       Include #include directives in the output\n");
+  printf ("  -ifoutput                 Describe skipped code blocks in output \n");
+  printf ("  -P                        Do not generate #line directives\n");
+  printf ("  -$                        Do not include '$' in identifiers\n");
+  printf ("  -remap                    Remap file names when including files.\n");
+  printf ("  -h or --help              Display this information\n");
+}
+\f
+
 /* Handle one command-line option in (argc, argv).
    Can be called multiple times, to handle multiple sets of options.
    Returns number of strings consumed.  */
@@ -6249,8 +6323,8 @@ cpp_handle_option (pfile, argc, argv)
   if (argv[i][0] != '-') {
     if (opts->out_fname != NULL)
       {
-       cpp_fatal (pfile, "Usage: %s [switches] input output", argv[0]);
-       return argc;
+       print_help ();
+       cpp_fatal (pfile, "Too many arguments");
       }
     else if (opts->in_fname != NULL)
       opts->out_fname = argv[i];
@@ -6576,6 +6650,12 @@ cpp_handle_option (pfile, argc, argv)
        opts->debug_output = 1;
       break;
       
+    case '-':
+      if (strcmp (argv[i], "--help") != 0)
+       return i;
+      print_help ();
+      break;
+       
     case 'v':
       fprintf (stderr, "GNU CPP version %s", version_string);
 #ifdef TARGET_VERSION
index bb33edf..48b94fc 100644 (file)
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -156,6 +156,11 @@ static int print_multi_directory;
 
 static int print_multi_lib;
 
+/* Flag saying to print the command line options understood by gcc and its
+   sub-processes.  */
+
+static int print_help_list;
+
 /* Flag indicating whether we should print the command and arguments */
 
 static int verbose_flag;
@@ -241,6 +246,7 @@ static void perror_with_name        PROTO((char *));
 static void pfatal_pexecute    PROTO((char *, char *));
 static void fatal              PVPROTO((char *, ...));
 static void error              PVPROTO((char *, ...));
+static void display_help       PROTO((void));
 
 void fancy_abort ();
 char *xmalloc ();
@@ -619,6 +625,7 @@ static struct compiler default_compilers[] =
                   %{traditional-cpp:-traditional}\
                  %{traditional} %{v:-version} %{pg:-p} %{p} %{f*}\
                  %{aux-info*}\
+                 %{--help:--help} \
                  %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} \
                  %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
                  %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
@@ -643,6 +650,7 @@ static struct compiler default_compilers[] =
                   %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} \
                   %{traditional} %{v:-version} %{pg:-p} %{p} %{f*}\
                   %{aux-info*}\
+                  %{--help:--help} \
                   %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
                   %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
               %{!S:as %a %Y\
@@ -2217,6 +2225,10 @@ execute ()
 
   if (verbose_flag)
     {
+      /* For help listings, put a blank line between sub-processes.  */
+      if (print_help_list)
+       fputc ('\n', stderr);
+      
       /* Print each piped command as a separate line.  */
       for (i = 0; i < n_commands ; i++)
        {
@@ -2414,6 +2426,79 @@ convert_filename (name, do_exe)
 }
 #endif
 \f
+/* Display the command line switches accepted by gcc.  */
+static void
+display_help ()
+{
+  printf ("Usage: %s [options] file...\n", programname);
+  printf ("Options:\n");
+
+  printf ("  --help                   Display this information\n");
+  if (! verbose_flag)
+    printf ("  (Use '-v --help' to display command line options of sub-processes)\n");
+  printf ("  -dumpspecs               Display all of the built in spec strings\n");
+  printf ("  -dumpversion             Display the version of the compiler\n");
+  printf ("  -dumpmachine             Display the compiler's target processor\n");
+  printf ("  -print-search-dirs       Display the directories in the compiler's search path\n");
+  printf ("  -print-libgcc-file-name  Display the name of the compiler's companion library\n");
+  printf ("  -print-file-name=<lib>   Display the full path to library <lib>\n");
+  printf ("  -print-prog-name=<prog>  Display the full path to compiler component <prog>\n");
+  printf ("  -print-multi-directory   Display the root directory for versions of libgcc\n");
+  printf ("  -print-multi-lib         Display the mapping between command line options and\n");
+  printf ("                            multiple library search directories\n");
+  printf ("  -Wa,<text>               Pass <text> on to the assembler\n");
+  printf ("  -Wp,<text>               Pass <text> on to the preprocessor\n");
+  printf ("  -Wl,<text>               Pass <text> on to the linker\n");
+  printf ("  -Xlinker <arg>           Pass <arg> on to the linker\n");
+  printf ("  -save-temps              Do not delete intermediate files\n");
+  printf ("  -pipe                    Use pipes rather than intermediate files\n");
+  printf ("  -specs=<file>            Override builtin specs with the contents of <file>\n");
+  printf ("  -B <directory>           Add <directory> to the compiler's search paths\n");
+  printf ("  -b <machine>             Run gcc for target <machine>, if installed\n");
+  printf ("  -V <version>             Run gcc version number <version>, if installed\n");
+  printf ("  -v                       Display the programs invoked by the compiler\n");
+  printf ("  -E                       Preprocess only; do not compile, assemble or link\n");
+  printf ("  -S                       Compile only; do not assemble or link\n");
+  printf ("  -c                       Compile and assemble, but do not link\n");
+  printf ("  -o <file>                Place the output into <file>\n");
+  printf ("  -x <language>            Specifiy the language of the following input files\n");
+  printf ("                            Permissable languages include: c c++ assembler none\n");
+  printf ("                            'none' means revert to the default behaviour of\n");
+  printf ("                            guessing the language based on the file's extension\n");
+
+  printf ("\nOptions starting with -g, -f, -m, -O or -W are automatically passed on to\n");
+  printf ("the various sub-processes invoked by %s.  In order to pass other options\n",
+         programname);
+  printf ("on to these processes the -W<letter> options must be used.\n");
+
+  /* The rest of the options are displayed by invocations of the various
+     sub-processes.  */
+}
+
+#define ADD_XXX_OPTION(name)                                           \
+static void                                                            \
+add_##name##_option (option, len)                                      \
+     char * option;                                                    \
+     int    len;                                                       \
+{                                                                      \
+  n_##name##_options++;                                                        \
+                                                                       \
+  if (! ##name##_options)                                              \
+    name##_options                                                     \
+      = (char **) xmalloc (n_##name##_options * sizeof (char **));     \
+  else                                                                 \
+    name##_options                                                     \
+      = (char **) xrealloc (##name##_options,                          \
+                           n_##name##_options * sizeof (char **));     \
+                                                                       \
+  name##_options [n_##name##_options - 1] = save_string (option, len);  \
+}
+
+ADD_XXX_OPTION (preprocessor)
+ADD_XXX_OPTION (assembler)
+ADD_XXX_OPTION (linker)
+     
+\f
 /* Create the vector `switches' and its contents.
    Store its length in `n_switches'.  */
 
@@ -2604,6 +2689,19 @@ process_command (argc, argv)
          printf ("%s\n", spec_machine);
          exit  (0);
        }
+      else if (strcmp (argv[i], "-fhelp") == 0)
+       {
+         /* translate_options () has turned --help into -fhelp.  */
+         print_help_list = 1;
+
+         /* We will be passing a dummy file on to the sub-processes.  */
+         n_infiles++;
+         n_switches++;
+         
+         add_preprocessor_option ("--help", 6);
+         add_assembler_option ("--help", 6);
+         add_linker_option ("--help", 6);
+       }
       else if (! strcmp (argv[i], "-print-search-dirs"))
        print_search_dirs = 1;
       else if (! strcmp (argv[i], "-print-libgcc-file-name"))
@@ -2621,60 +2719,34 @@ process_command (argc, argv)
          int prev, j;
          /* Pass the rest of this option to the assembler.  */
 
-         n_assembler_options++;
-         if (!assembler_options)
-           assembler_options
-             = (char **) xmalloc (n_assembler_options * sizeof (char **));
-         else
-           assembler_options
-             = (char **) xrealloc (assembler_options,
-                                   n_assembler_options * sizeof (char **));
-
          /* Split the argument at commas.  */
          prev = 4;
          for (j = 4; argv[i][j]; j++)
            if (argv[i][j] == ',')
              {
-               assembler_options[n_assembler_options - 1]
-                 = save_string (argv[i] + prev, j - prev);
-               n_assembler_options++;
-               assembler_options
-                 = (char **) xrealloc (assembler_options,
-                                       n_assembler_options * sizeof (char **));
+               add_assembler_option (argv[i] + prev, j - prev);
                prev = j + 1;
              }
+         
          /* Record the part after the last comma.  */
-         assembler_options[n_assembler_options - 1] = argv[i] + prev;
+         add_assembler_option (argv[i] + prev, j - prev);
        }
       else if (! strncmp (argv[i], "-Wp,", 4))
        {
          int prev, j;
          /* Pass the rest of this option to the preprocessor.  */
 
-         n_preprocessor_options++;
-         if (!preprocessor_options)
-           preprocessor_options
-             = (char **) xmalloc (n_preprocessor_options * sizeof (char **));
-         else
-           preprocessor_options
-             = (char **) xrealloc (preprocessor_options,
-                                   n_preprocessor_options * sizeof (char **));
-
          /* Split the argument at commas.  */
          prev = 4;
          for (j = 4; argv[i][j]; j++)
            if (argv[i][j] == ',')
              {
-               preprocessor_options[n_preprocessor_options - 1]
-                 = save_string (argv[i] + prev, j - prev);
-               n_preprocessor_options++;
-               preprocessor_options
-                 = (char **) xrealloc (preprocessor_options,
-                                       n_preprocessor_options * sizeof (char **));
+               add_preprocessor_option (argv[i] + prev, j - prev);
                prev = j + 1;
              }
+         
          /* Record the part after the last comma.  */
-         preprocessor_options[n_preprocessor_options - 1] = argv[i] + prev;
+         add_preprocessor_option (argv[i] + prev, j - prev);
        }
       else if (argv[i][0] == '+' && argv[i][1] == 'e')
        /* The +e options to the C++ front-end.  */
@@ -3010,6 +3082,25 @@ process_command (argc, argv)
        ;
       else if (! strcmp (argv[i], "-print-multi-directory"))
        ;
+      else if (strcmp (argv[i], "-fhelp") == 0)
+       {
+         if (verbose_flag)
+           {
+             /* Create a dummy input file, so that we can pass --help on to
+                the various sub-processes.  */
+             infiles[n_infiles].language = "c";
+             infiles[n_infiles++].name   = "help-dummy";
+             
+             /* Preserve the --help switch so that it can bet caught by the
+                cc1 spec string.  */
+             switches[n_switches].part1     = "--help";
+             switches[n_switches].args      = 0;
+             switches[n_switches].live_cond = 0;
+             switches[n_switches].valid     = 0;
+             
+             n_switches++;
+           }
+       }
       else if (argv[i][0] == '+' && argv[i][1] == 'e')
        {
          /* Compensate for the +e options to the C++ front-end;
@@ -3634,16 +3725,7 @@ do_spec_1 (spec, inswitch, soft_matched_part)
                  }
 
              /* This option is new; add it.  */
-             n_linker_options++;
-             if (!linker_options)
-               linker_options
-                 = (char **) xmalloc (n_linker_options * sizeof (char **));
-             else
-               linker_options
-                 = (char **) xrealloc (linker_options,
-                                       n_linker_options * sizeof (char **));
-
-             linker_options[n_linker_options - 1] = string;
+             add_linker_option (string, strlen (string));
            }
            break;
 
@@ -4789,6 +4871,23 @@ main (argc, argv)
       exit (0);
     }
 
+  if (print_help_list)
+    {
+      display_help ();
+
+      if (! verbose_flag)
+       {
+         printf ("\nReport bugs to egcs-bugs@cygnus.com.\n");
+         printf ("Please see the file BUGS (included with the sources) first.\n");
+         
+         exit (0);
+       }
+
+      /* We do not exit here.  Instead we have created a fake input file
+        called 'help-dummy' which needs to be compiled, and we pass this
+        on the the various sub-processes, along with the --help switch.  */
+    }
+  
   if (verbose_flag)
     {
       int n;
@@ -4966,6 +5065,12 @@ main (argc, argv)
     delete_failure_queue ();
   delete_temp_files ();
 
+  if (print_help_list)
+    {
+      printf ("\nReport bugs to egcs-bugs@cygnus.com.\n");
+      printf ("Please see the file BUGS (included with the sources) first.\n");
+    }
+  
   exit (error_count > 0 ? (signal_count ? 2 : 1) : 0);
   /* NOTREACHED */
   return 0;
index 32c5a75..1c5d3b6 100644 (file)
@@ -546,10 +546,13 @@ bits in @code{target_flags}.  Its definition is an initializer
 with a subgrouping for each command option.
 
 Each subgrouping contains a string constant, that defines the option
-name, and a number, which contains the bits to set in
-@code{target_flags}.  A negative number says to clear bits instead;
-the negative of the number is which bits to clear.  The actual option
-name is made by appending @samp{-m} to the specified name.
+name, a number, which contains the bits to set in
+@code{target_flags}, and a second string which is the description
+displayed by --help.  If the number is negative then the bits specified
+by the number are cleared instead of being set.  If the description
+string is present but empty, then no help information will be displayed
+for that option, but it will not count as an undocumented option.  The
+actual option name is made by appending @samp{-m} to the specified name.
 
 One of the subgroupings should have a null string.  The number in
 this grouping is the default value for @code{target_flags}.  Any
@@ -560,9 +563,9 @@ with opposite meanings, and picks the latter as the default:
 
 @smallexample
 #define TARGET_SWITCHES \
-  @{ @{ "68020", 1@},      \
-    @{ "68000", -1@},     \
-    @{ "", 1@}@}
+  @{ @{ "68020", 1, "" @},      \
+    @{ "68000", -1, "Compile for the 68000" @}, \
+    @{ "", 1, "" @}@}
 @end smallexample
 
 @findex TARGET_OPTIONS
@@ -572,10 +575,10 @@ options that have values.  Its definition is an initializer with a
 subgrouping for each command option.
 
 Each subgrouping contains a string constant, that defines the fixed part
-of the option name, and the address of a variable.  The variable, type
-@code{char *}, is set to the variable part of the given option if the fixed
-part matches.  The actual option name is made by appending @samp{-m} to the
-specified name.
+of the option name, the address of a variable, and a description string.
+The variable, type @code{char *}, is set to the variable part of the
+given option if the fixed part matches.  The actual option name is made
+by appending @samp{-m} to the specified name.
 
 Here is an example which defines @samp{-mshort-data-@var{number}}.  If the
 given option is @samp{-mshort-data-512}, the variable @code{m88k_short_data}
@@ -584,7 +587,7 @@ will be set to the string @code{"512"}.
 @smallexample
 extern char *m88k_short_data;
 #define TARGET_OPTIONS \
- @{ @{ "short-data-", &m88k_short_data @} @}
+ @{ @{ "short-data-", &m88k_short_data, "Specify the size of the short data section" @} @}
 @end smallexample
 
 @findex TARGET_VERSION
index d63b0c2..fb6b859 100644 (file)
@@ -209,6 +209,7 @@ static void close_dump_file PROTO((void (*) (FILE *, rtx), rtx));
 static void dump_rtl PROTO((char *, tree, void (*) (FILE *, rtx), rtx));
 static void clean_dump_file PROTO((char *));
 static void compile_file PROTO((char *));
+static void display_help PROTO ((void));
 
 void print_version ();
 int print_single_switch ();
@@ -722,216 +723,376 @@ int flag_strict_aliasing = 0;
 
 extern int flag_dump_unnumbered;
 
+
+/* Table of supported debugging formats.  */
+static struct
+{
+  char * arg;
+  /* Since PREFERRED_DEBUGGING_TYPE isn't necessarily a
+     constant expression, we use NO_DEBUG in its place.  */
+  enum debug_info_type debug_type;
+  int use_extensions_p;
+  char * description;
+} *da,
+debug_args[] =
+{
+  { "g",    NO_DEBUG, DEFAULT_GDB_EXTENSIONS,
+    "Generate default debug format output" },
+  { "ggdb", NO_DEBUG, 1, "Generate default extended debug format output" },
+#ifdef DBX_DEBUGGING_INFO
+  { "gstabs",  DBX_DEBUG, 0, "Generate STABS format debug output" },
+  { "gstabs+", DBX_DEBUG, 1, "Generate extended STABS format debug output" },
+#endif
+#ifdef DWARF_DEBUGGING_INFO
+  { "gdwarf",  DWARF_DEBUG, 0, "Generate DWARF-1 format debug output"},
+  { "gdwarf+", DWARF_DEBUG, 1,
+    "Generated extended DWARF-1 format debug output" },
+#endif
+#ifdef DWARF2_DEBUGGING_INFO
+  { "gdwarf-2", DWARF2_DEBUG, 0, "Enable DWARF-2 debug output" },
+#endif
+#ifdef XCOFF_DEBUGGING_INFO
+  { "gxcoff",  XCOFF_DEBUG, 0, "Generate XCOFF format debug output" },
+  { "gxcoff+", XCOFF_DEBUG, 1, "Generate extended XCOFF format debug output" },
+#endif
+#ifdef SDB_DEBUGGING_INFO
+  { "gcoff", SDB_DEBUG, 0, "Generate COFF format debug output" },
+#endif
+  { 0, 0, 0 }
+};
+
+typedef struct
+{
+  char * string;
+  int *  variable;
+  int    on_value;
+  char * description;
+}
+lang_independent_options;
+
 /* Table of language-independent -f options.
    STRING is the option name.  VARIABLE is the address of the variable.
    ON_VALUE is the value to store in VARIABLE
     if `-fSTRING' is seen as an option.
    (If `-fno-STRING' is seen as an option, the opposite value is stored.)  */
 
-struct { char *string; int *variable; int on_value;} f_options[] =
+lang_independent_options f_options[] =
 {
-  {"float-store", &flag_float_store, 1},
-  {"volatile", &flag_volatile, 1},
-  {"volatile-global", &flag_volatile_global, 1},
-  {"defer-pop", &flag_defer_pop, 1},
-  {"omit-frame-pointer", &flag_omit_frame_pointer, 1},
-  {"cse-follow-jumps", &flag_cse_follow_jumps, 1},
-  {"cse-skip-blocks", &flag_cse_skip_blocks, 1},
-  {"expensive-optimizations", &flag_expensive_optimizations, 1},
-  {"thread-jumps", &flag_thread_jumps, 1},
-  {"strength-reduce", &flag_strength_reduce, 1},
-  {"unroll-loops", &flag_unroll_loops, 1},
-  {"unroll-all-loops", &flag_unroll_all_loops, 1},
-  {"move-all-movables", &flag_move_all_movables, 1},
-  {"reduce-all-givs", &flag_reduce_all_givs, 1},
-  {"writable-strings", &flag_writable_strings, 1},
-  {"peephole", &flag_no_peephole, 0},
-  {"force-mem", &flag_force_mem, 1},
-  {"force-addr", &flag_force_addr, 1},
-  {"function-cse", &flag_no_function_cse, 0},
-  {"inline-functions", &flag_inline_functions, 1},
-  {"keep-inline-functions", &flag_keep_inline_functions, 1},
-  {"inline", &flag_no_inline, 0},
-  {"keep-static-consts", &flag_keep_static_consts, 1},
-  {"syntax-only", &flag_syntax_only, 1},
-  {"shared-data", &flag_shared_data, 1},
-  {"caller-saves", &flag_caller_saves, 1},
-  {"pcc-struct-return", &flag_pcc_struct_return, 1},
-  {"reg-struct-return", &flag_pcc_struct_return, 0},
-  {"delayed-branch", &flag_delayed_branch, 1},
-  {"gcse", &flag_gcse, 1},
-  {"rerun-cse-after-loop", &flag_rerun_cse_after_loop, 1},
-  {"rerun-loop-opt", &flag_rerun_loop_opt, 1},
-  {"pretend-float", &flag_pretend_float, 1},
-  {"schedule-insns", &flag_schedule_insns, 1},
-  {"schedule-insns2", &flag_schedule_insns_after_reload, 1},
+  {"float-store", &flag_float_store, 1,
+   "Do not store floats in registers" },
+  {"volatile", &flag_volatile, 1,
+   "Consider all mem refs through pointers as volatile"},
+  {"volatile-global", &flag_volatile_global, 1,
+   "Consider all mem refs to global data to be volatile" },
+  {"defer-pop", &flag_defer_pop, 1,
+   "Defer popping functions args from stack until later" },
+  {"omit-frame-pointer", &flag_omit_frame_pointer, 1,
+   "When possible do not generate stack frames"},
+  {"cse-follow-jumps", &flag_cse_follow_jumps, 1,
+   "When running CSE, follow jumps to their targets" },
+  {"cse-skip-blocks", &flag_cse_skip_blocks, 1,
+   "When running CSE, follow conditional jumps" },
+  {"expensive-optimizations", &flag_expensive_optimizations, 1,
+   "Perform a number of minor, expensive optimisations" },
+  {"thread-jumps", &flag_thread_jumps, 1,
+   "Perform jump threading optimisations"},
+  {"strength-reduce", &flag_strength_reduce, 1,
+   "Perform strength reduction optimisations" },
+  {"unroll-loops", &flag_unroll_loops, 1,
+   "Perform loop unrolling when interation count is known" },
+  {"unroll-all-loops", &flag_unroll_all_loops, 1,
+   "Perofm loop onrolling for all loops" },
+  {"move-all-movables", &flag_move_all_movables, 1,
+   "Force all loop invariant computations out of loops" },
+  {"reduce-all-givs", &flag_reduce_all_givs, 1,
+   "Strength reduce all loop general induction variables" },
+  {"writable-strings", &flag_writable_strings, 1,
+   "Store strings in writable data section" },
+  {"peephole", &flag_no_peephole, 0,
+   "Enable machine specific peephole optimisations" },
+  {"force-mem", &flag_force_mem, 1,
+   "Copy memory operands into registers before using" },
+  {"force-addr", &flag_force_addr, 1,
+   "Copy memory address constants into regs before using" },
+  {"function-cse", &flag_no_function_cse, 0,
+   "Allow function addresses to be held in registers" },
+  {"inline-functions", &flag_inline_functions, 1,
+   "Integrate simple functions into their callers" },
+  {"keep-inline-functions", &flag_keep_inline_functions, 1,
+   "Generate code for funcs even if they are fully inlined" },
+  {"inline", &flag_no_inline, 0,
+   "Pay attention to the 'inline' keyword"},
+  {"keep-static-consts", &flag_keep_static_consts, 1,
+   "Emit static const variables even if they are not used" },
+  {"syntax-only", &flag_syntax_only, 1,
+   "Check for syntax errors, then stop" },
+  {"shared-data", &flag_shared_data, 1,
+   "Mark data as shared rather than private" },
+  {"caller-saves", &flag_caller_saves, 1,
+   "Enable saving registers around function calls" },
+  {"pcc-struct-return", &flag_pcc_struct_return, 1,
+   "Return 'short' aggregates in memory, not registers" },
+  {"reg-struct-return", &flag_pcc_struct_return, 0,
+   "Return 'short' aggregates in registers" },
+  {"delayed-branch", &flag_delayed_branch, 1,
+   "Attempt to fill delay slots of branch instructions" },
+  {"gcse", &flag_gcse, 1,
+   "Perform the global common subexpression elimination" },
+  {"rerun-cse-after-loop", &flag_rerun_cse_after_loop, 1,
+   "Run CSE pass after loop optimisations"},
+  {"rerun-loop-opt", &flag_rerun_loop_opt, 1,
+   "Run the loop optimiser twice"},
+  {"pretend-float", &flag_pretend_float, 1,
+   "Pretend that host and target use the same FP format"},
+  {"schedule-insns", &flag_schedule_insns, 1,
+   "Reschedule instructions to avoid pipeline stalls"},
+  {"schedule-insns2", &flag_schedule_insns_after_reload, 1,
+  "Run two passes of the instruction scheduler"},
 #ifdef HAIFA
-  {"sched-interblock",&flag_schedule_interblock, 1},
-  {"sched-spec",&flag_schedule_speculative, 1},
-  {"sched-spec-load",&flag_schedule_speculative_load, 1},
-  {"sched-spec-load-dangerous",&flag_schedule_speculative_load_dangerous, 1},
-  {"branch-count-reg",&flag_branch_on_count_reg, 1},
+  {"sched-interblock",&flag_schedule_interblock, 1,
+   "Enable scheduling across basic blocks" },
+  {"sched-spec",&flag_schedule_speculative, 1,
+   "Allow speculative motion of non-loads" },
+  {"sched-spec-load",&flag_schedule_speculative_load, 1,
+   "Allow speculative motion of some loads" },
+  {"sched-spec-load-dangerous",&flag_schedule_speculative_load_dangerous, 1,
+   "Allow speculative motion of more loads" },
+  {"branch-count-reg",&flag_branch_on_count_reg, 1,
+   "Replace add,compare,branch with branch on count register"},
 #endif  /* HAIFA */
-  {"pic", &flag_pic, 1},
-  {"PIC", &flag_pic, 2},
-  {"exceptions", &flag_exceptions, 1},
-  {"new-exceptions", &flag_new_exceptions, 1},
-  {"sjlj-exceptions", &exceptions_via_longjmp, 1},
-  {"asynchronous-exceptions", &asynchronous_exceptions, 1},
-  {"profile-arcs", &profile_arc_flag, 1},
-  {"test-coverage", &flag_test_coverage, 1},
-  {"branch-probabilities", &flag_branch_probabilities, 1},
-  {"fast-math", &flag_fast_math, 1},
-  {"common", &flag_no_common, 0},
-  {"inhibit-size-directive", &flag_inhibit_size_directive, 1},
-  {"function-sections", &flag_function_sections, 1},
-  {"verbose-asm", &flag_verbose_asm, 1},
-  {"gnu-linker", &flag_gnu_linker, 1},
-  {"regmove", &flag_regmove, 1},
+  {"pic", &flag_pic, 1,
+   "Generate position independent code, if possible"},
+  {"PIC", &flag_pic, 2, ""},
+  {"exceptions", &flag_exceptions, 1,
+   "Enable exception handling" },
+  {"new-exceptions", &flag_new_exceptions, 1,
+   "Use the new model for exception handling" },
+  {"sjlj-exceptions", &exceptions_via_longjmp, 1,
+   "Use setjmp/longjmp to handle exceptions" },
+  {"asynchronous-exceptions", &asynchronous_exceptions, 1,
+   "Support asynchronous exceptions" },
+  {"profile-arcs", &profile_arc_flag, 1,
+   "Insert arc based program profiling code" },
+  {"test-coverage", &flag_test_coverage, 1,
+   "Create data files needed by gcov" },
+  {"branch-probabilities", &flag_branch_probabilities, 1,
+   "Use profiling information for branch porbabilities" },
+  {"fast-math", &flag_fast_math, 1,
+   "Improve FP speed by violating ANSI & IEEE rules" },
+  {"common", &flag_no_common, 0,
+   "Do not put unitialised globals in the common section" },
+  {"inhibit-size-directive", &flag_inhibit_size_directive, 1,
+   "Do not generate .size directives" },
+  {"function-sections", &flag_function_sections, 1,
+   "place each function into its own section" },
+  {"verbose-asm", &flag_verbose_asm, 1,
+   "Add extra commentry to assembler output"},
+  {"gnu-linker", &flag_gnu_linker, 1,
+   "Output GNU ld formatted global initialisers"},
+  {"regmove", &flag_regmove, 1,
+   "Enables a regoster move optimisation"},
   {"optimize-register-move", &flag_regmove, 1},
-  {"pack-struct", &flag_pack_struct, 1},
-  {"stack-check", &flag_stack_check, 1},
-  {"argument-alias", &flag_argument_noalias, 0},
-  {"argument-noalias", &flag_argument_noalias, 1},
-  {"argument-noalias-global", &flag_argument_noalias, 2},
-  {"strict-aliasing", &flag_strict_aliasing, 1},
-  {"check-memory-usage", &flag_check_memory_usage, 1},
-  {"prefix-function-name", &flag_prefix_function_name, 1},
+  {"pack-struct", &flag_pack_struct, 1,
+   "Pack structure members together without holes" },
+  {"stack-check", &flag_stack_check, 1,
+   "Insert stack checking code into the program" },
+  {"argument-alias", &flag_argument_noalias, 0,
+   "Specify that arguments may alias each other & globals"},
+  {"argument-noalias", &flag_argument_noalias, 1,
+   "Assume arguments may alias globals but not each other"},
+  {"argument-noalias-global", &flag_argument_noalias, 2,
+   "Assume arguments do not alias each other or globals" },
+  {"strict-aliasing", &flag_strict_aliasing, 1,
+   "Assume strict aliasing rules apply" },
+  {"check-memory-usage", &flag_check_memory_usage, 1,
+   "Generate code to check every memory access" },
+  {"prefix-function-name", &flag_prefix_function_name, 1,
+   "Add a prefix to all function names" },
   {"dump-unnumbered", &flag_dump_unnumbered, 1}
 };
 
+#define NUM_ELEM(a)  (sizeof (a) / sizeof ((a)[0]))
+
 /* Table of language-specific options.  */
 
-char *lang_options[] =
+static struct lang_opt
 {
-  "-ansi",
-  "-fallow-single-precision",
-
-  "-fsigned-bitfields",
-  "-funsigned-bitfields",
-  "-fno-signed-bitfields",
-  "-fno-unsigned-bitfields",
-  "-fsigned-char",
-  "-funsigned-char",
-  "-fno-signed-char",
-  "-fno-unsigned-char",
-
-  "-ftraditional",
-  "-traditional",
-  "-fnotraditional",
-  "-fno-traditional",
-
-  "-fasm",
-  "-fno-asm",
-  "-fbuiltin",
-  "-fno-builtin",
-  "-fhosted",
-  "-fno-hosted",
-  "-ffreestanding",
-  "-fno-freestanding",
-  "-fcond-mismatch",
-  "-fno-cond-mismatch",
-  "-fdollars-in-identifiers",
-  "-fno-dollars-in-identifiers",
-  "-fident",
-  "-fno-ident",
-  "-fshort-double",
-  "-fno-short-double",
-  "-fshort-enums",
-  "-fno-short-enums",
-
-  "-Wall",
-  "-Wbad-function-cast",
-  "-Wno-bad-function-cast",
-  "-Wcast-qual",
-  "-Wno-cast-qual",
-  "-Wchar-subscripts",
-  "-Wno-char-subscripts",
-  "-Wcomment",
-  "-Wno-comment",
-  "-Wcomments",
-  "-Wno-comments",
-  "-Wconversion",
-  "-Wno-conversion",
-  "-Wformat",
-  "-Wno-format",
-  "-Wimport",
-  "-Wno-import",
-  "-Wimplicit-function-declaration",
-  "-Wno-implicit-function-declaration",
-  "-Werror-implicit-function-declaration",
-  "-Wimplicit-int",
-  "-Wno-implicit-int",
-  "-Wimplicit",
-  "-Wno-implicit",
-  "-Wlong-long",
-  "-Wno-long-long",
-  "-Wmain",
-  "-Wno-main",
-  "-Wmissing-braces",
-  "-Wno-missing-braces",
-  "-Wmissing-declarations",
-  "-Wno-missing-declarations",
-  "-Wmissing-prototypes",
-  "-Wno-missing-prototypes",
-  "-Wmultichar",
-  "-Wno-multichar",
-  "-Wnested-externs",
-  "-Wno-nested-externs",
-  "-Wparentheses",
-  "-Wno-parentheses",
-  "-Wpointer-arith",
-  "-Wno-pointer-arith",
-  "-Wredundant-decls",
-  "-Wno-redundant-decls",
-  "-Wsign-compare",
-  "-Wno-sign-compare",
-  "-Wunknown-pragmas",
-  "-Wno-unknown-pragmas",
-  "-Wstrict-prototypes",
-  "-Wno-strict-prototypes",
-  "-Wtraditional",
-  "-Wno-traditional",
-  "-Wtrigraphs",
-  "-Wno-trigraphs",
-  "-Wundef",
-  "-Wno-undef",
-  "-Wwrite-strings",
-  "-Wno-write-strings",
-
-  /* these are for obj c */
-  "-lang-objc",
-  "-gen-decls",
-  "-fgnu-runtime",
-  "-fno-gnu-runtime",
-  "-fnext-runtime",
-  "-fno-next-runtime",
-  "-Wselector",
-  "-Wno-selector",
-  "-Wprotocol",
-  "-Wno-protocol",
-  "-print-objc-runtime-info",
+  char * option;
+  char * description;
+}
+documented_lang_options[] =
+{
+  /* In order not to overload the --help output, the convention
+     used here is to only describe those options which are not
+     enabled by default.  */
+
+  { "-ansi", "Compile just for ANSI C" },
+  { "-fallow-single-precision",
+    "Do not promote floats to double if using -traditional" },
+
+  { "-fsigned-bitfields", "" },
+  { "-funsigned-bitfields","Make bitfields by unsigned by default" },
+  { "-fno-signed-bitfields", "" },
+  { "-fno-unsigned-bitfields","" },
+  { "-fsigned-char", "Make 'char' be signed by default"},
+  { "-funsigned-char", "Make 'char' be unsigned by default"},
+  { "-fno-signed-char", "" },
+  { "-fno-unsigned-char", "" },
+
+  { "-ftraditional", "" },
+  { "-traditional", "Attempt to support traditional K&R style C"},
+  { "-fnotraditional", "" },
+  { "-fno-traditional", "" },
+
+  { "-fasm", "" },
+  { "-fno-asm", "Do not recognise the 'asm' keyword" },
+  { "-fbuiltin", "" },
+  { "-fno-builtin", "Do not recognise any built in functions" },
+  { "-fhosted", "Assume normal C execution environment" },
+  { "-fno-hosted", "" },
+  { "-ffreestanding",
+    "Assume that standard libraries & main might not exist" },
+  { "-fno-freestanding", "" },
+  { "-fcond-mismatch", "Allow different types as args of ? operator"},
+  { "-fno-cond-mismatch", "" },
+  { "-fdollars-in-identifiers", "Allow the use of $ inside indentifiers" },
+  { "-fno-dollars-in-identifiers", "" },
+  { "-fident", "" },
+  { "-fno-ident", "Ignore #ident directives" },
+  { "-fshort-double", "Use the same size for double as for float" },
+  { "-fno-short-double", "" },
+  { "-fshort-enums", "Use the smallest fitting integer to hold enums"},
+  { "-fno-short-enums", "" },
+
+  { "-Wall", "Enable most warning messages" },
+  { "-Wbad-function-cast",
+    "Warn about casting functions to incompatible types" },
+  { "-Wno-bad-function-cast", "" },
+  { "-Wcast-qual", "Warn about casts which discard qualifiers"},
+  { "-Wno-cast-qual", "" },
+  { "-Wchar-subscripts", "Warn about subscripts whoes type is 'char'"},
+  { "-Wno-char-subscripts", "" },
+  { "-Wcomment", "Warn if nested comments are detected" },
+  { "-Wno-comment", },
+  { "-Wcomments", },
+  { "-Wno-comments", },
+  { "-Wconversion", "Warn about possibly confusing type conversions" },
+  { "-Wno-conversion", "" },
+  { "-Wformat", "Warn about printf format anomalies" },
+  { "-Wno-format", "" },
+  { "-Wimplicit-function-declaration",
+    "Warn about implicit function declarations" },
+  { "-Wno-implicit-function-declaration", "" },
+  { "-Werror-implicit-function-declaration", "" },
+  { "-Wimplicit-int", "Warn when a declaration does not specify a type" },
+  { "-Wno-implicit-int", "" },
+  { "-Wimplicit", "" },
+  { "-Wno-implicit", "" },
+  { "-Wimport", "Warn about the use of the #import directive" },
+  { "-Wno-import", "" },
+  { "-Wlong-long","" },
+  { "-Wno-long-long", "Do not warn about using 'long long' when -pedantic" },
+  { "-Wmain", "Warn about suspicious declarations of main" },
+  { "-Wno-main", "" },
+  { "-Wmissing-braces",
+    "Warn about possibly missing braces around initialisers" },
+  { "-Wno-missing-braces", "" },
+  { "-Wmissing-declarations",
+    "Warn about global funcs without previous declarations"},
+  { "-Wno-missing-declarations", "" },
+  { "-Wmissing-prototypes", "Warn about global funcs without prototypes" },
+  { "-Wno-missing-prototypes", "" },
+  { "-Wmultichar", "Warn about use of multicharacter literals"},
+  { "-Wno-multichar", "" },
+  { "-Wnested-externs", "Warn about externs not at file scope level" },
+  { "-Wno-nested-externs", "" },
+  { "-Wparentheses", "Warn about possible missing parentheses" },
+  { "-Wno-parentheses", "" },
+  { "-Wpointer-arith", "Warn about function pointer arithmetic" },
+  { "-Wno-pointer-arith", "" },
+  { "-Wredundant-decls",
+    "Warn about multiple declarations of the same object" },
+  { "-Wno-redundant-decls", "" },
+  { "-Wsign-compare", "Warn about signed/unsigned comparisons" },
+  { "-Wno-sign-compare", "" },
+  { "-Wunknown-pragmas", "Warn about unrecognised pragmas" },
+  { "-Wno-unknown-pragmas", "" },
+  { "-Wstrict-prototypes", "Warn about non-prototyped function decls" },
+  { "-Wno-strict-prototypes", "" },
+  { "-Wtraditional", "Warn about constructs whoes meaning change in ANSI C"},
+  { "-Wno-traditional", "" },
+  { "-Wtrigraphs", "Warn when trigraphs are encountered" },
+  { "-Wno-trigraphs", "" },
+  { "-Wundef", "" },
+  { "-Wno-undef", "" },
+  { "-Wwrite-strings", "Mark strings as 'const char *'"},
+  { "-Wno-write-strings", "" },
 
   /* These are for languages with USE_CPPLIB.  */
-  "-A",
-  "-D",
-  "-I",
-  "-U",
-  "-idirafter",
-  "-iprefix",
-  "-isystem",
-  "-lang-c",
-  "-lang-c89",
-  "-lang-c++",
-  "-nostdinc",
-  "-nostdinc++",
-  "-trigraphs",
-  "-undef",
-  "-remap",
+  /* These options are already documented in cpplib.c */
+  { "-A", "" },
+  { "-D", "" },
+  { "-I", "" },
+  { "-U", "" },
+  { "-idirafter", "" },
+  { "-iprefix", "" },
+  { "-isystem", "" },
+  { "-lang-c", "" },
+  { "-lang-c89", "" },
+  { "-lang-c++", "" },
+  { "-nostdinc", "" },
+  { "-nostdinc++", "" },
+  { "-trigraphs", "" },
+  { "-undef", "" },
+  { "-remap", "" },
+  
+#define DEFINE_LANG_NAME(NAME) { NULL, NAME },
+  
+  /* These are for obj c.  */
+  DEFINE_LANG_NAME ("Objective C")
+  
+  { "-lang-objc", "" },
+  { "-gen-decls", "Dump decls to a .decl file" },
+  { "-fgnu-runtime", "Generate code for GNU runtime envrionment" },
+  { "-fno-gnu-runtime", "" },
+  { "-fnext-runtime", "Generate code for NeXT runtime environment" },
+  { "-fno-next-runtime", "" },
+  { "-Wselector", "Warn if a selector has multiple methods" },
+  { "-Wno-selector", "" },
+  { "-Wprotocol", "" },
+  { "-Wno-protocol", "Do not warn if inherited methods are unimplemented"},
+  { "-print-objc-runtime-info",
+    "Generate C header of platform specific features" },
 
 #include "options.h"
-  0
+  
 };
+
+/* Here is a table, controlled by the tm.h file, listing each -m switch
+   and which bits in `target_switches' it should set or clear.
+   If VALUE is positive, it is bits to set.
+   If VALUE is negative, -VALUE is bits to clear.
+   (The sign bit is not used so there is no confusion.)  */
+
+struct
+{
+  char * name;
+  int    value;
+  char * description;
+}
+target_switches [] = TARGET_SWITCHES;
+
+/* This table is similar, but allows the switch to have a value.  */
+
+#ifdef TARGET_OPTIONS
+struct
+{
+  char *  prefix;
+  char ** variable;
+  char *  description;
+}
+target_options [] = TARGET_OPTIONS;
+#endif
 \f
 /* Options controlling warnings */
 
@@ -998,16 +1159,21 @@ int warn_aggregate_return;
 
 /* Likewise for -W.  */
 
-struct { char *string; int *variable; int on_value;} W_options[] =
+lang_independent_options W_options[] =
 {
-  {"unused", &warn_unused, 1},
-  {"error", &warnings_are_errors, 1},
-  {"shadow", &warn_shadow, 1},
-  {"switch", &warn_switch, 1},
-  {"aggregate-return", &warn_aggregate_return, 1},
-  {"cast-align", &warn_cast_align, 1},
-  {"uninitialized", &warn_uninitialized, 1},
-  {"inline", &warn_inline, 1}
+  {"unused", &warn_unused, 1, "Warn when a variable is unused" },
+  {"error", &warnings_are_errors, 1, ""},
+  {"shadow", &warn_shadow, 1, "Warn when one local variable shadows another" },
+  {"switch", &warn_switch, 1,
+   "Warn about enumerated switches missing a specific case" },
+  {"aggregate-return", &warn_aggregate_return, 1,
+   "Warn about returning structures, unions or arrays" },
+  {"cast-align", &warn_cast_align, 1,
+   "Warn about pointer casts which increase alignment" },
+  {"uninitialized", &warn_uninitialized, 1,
+   "Warn about unitialized automatic variables"},
+  {"inline", &warn_inline, 1,
+   "Warn when an inlined function cannot be inlined"}
 };
 \f
 /* Output files for assembler code (real compiler output)
@@ -3767,6 +3933,232 @@ rest_of_compilation (decl)
   parse_time -= get_run_time () - start_time;
 }
 \f
+static void
+display_help ()
+{
+  int    undoc;
+  long  i;
+  char * lang;
+  
+  printf ("Usage: %s input [switches]\n", progname);
+  printf ("Switches:\n");
+  printf ("  -ffixed-<register>      Mark <register> as being unavailable to the compiler\n");
+  printf ("  -fcall-used-<register>  Mark <register> as being corrupted by function calls\n");
+  printf ("  -fcall-saved-<register> Mark <register> as being preserved across functions\n");
+
+  for (i = NUM_ELEM (f_options); i--;)
+    {
+      char * description = f_options[i].description;
+      
+      if (description != NULL && * description != 0)
+       printf ("  -f%-21s %s\n",
+               f_options[i].string, description);
+    }
+  
+  printf ("  -O[number]              Set optimisation level to [number]\n");
+  printf ("  -Os                     Optimise for space rather than speed\n");
+  printf ("  -pedantic               Issue warnings needed by strict compliance to ANSI C\n");
+  printf ("  -pedantic-errors        Like -pedantic except that errors are produced\n");
+  printf ("  -w                      Suppress warnings\n");
+  printf ("  -W                      Enable extra warnings\n");
+  
+  for (i = NUM_ELEM (W_options); i--;)
+    {
+      char * description = W_options[i].description;
+      
+      if (description != NULL && * description != 0)
+       printf ("  -W%-21s %s\n",
+               W_options[i].string, description);
+    }
+  
+  printf ("  -Wid-clash-<num>        Warn if 2 identifiers have the same first <num> chars\n");
+  printf ("  -Wlarger-than-<number>  Warn if an object is larger than <number> bytes\n");
+  printf ("  -p                      Enable function profiling\n");
+#if defined (BLOCK_PROFILER) || defined (FUNCTION_BLOCK_PROFILER)
+  printf ("  -a                      Enable block profiling \n");
+#endif  
+#if defined (BLOCK_PROFILER) || defined (FUNCTION_BLOCK_PROFILER) || defined FUNCTION_BLOCK_PROFILER_EXIT
+  printf ("  -ax                     Enable jump profiling \n");
+#endif  
+  printf ("  -o <file>               Place output into <file> \n");
+  printf ("  -G <number>             Put global and static data smaller than <number>\n");
+  printf ("                           bytes into a special section [on some targets]\n");
+  
+  for (i = NUM_ELEM (debug_args); i--;)
+    {
+      if (debug_args[i].description != NULL)
+       printf ("  -%-22s %s\n", debug_args[i].arg, debug_args[i].description);
+    }
+  
+  printf ("  -aux-info <file>        Emit declaration info into <file>.X\n");
+  printf ("  -quiet                  Do not display functions compiled or elapsed time\n");
+  printf ("  -version                Display the compiler's version\n");
+  printf ("  -d[letters]             Enable dumps from specific passes of the compiler\n");
+  printf ("  -dumpbase <file>        Base name to be used for dumps from specific passes\n");
+#if defined HAIFA || defined INSN_SCHEDULING
+  printf ("  -sched-verbose-<number> Set the verbosity level of the scheduler\n");
+#endif
+  printf ("  --help                  Display this information\n");
+
+  undoc = 0;
+  lang  = "language";
+  
+  /* Display descriptions of language specific options.
+     If there is no description, note that there is an undocumented option.
+     If the description is empty, do not display anything.  (This allows
+     options to be deliberately undocumented, for whatever reason).
+     If the option string is missing, then this is a marker, indicating
+     that the description string is in fact the name of a language, whoes
+     language specific options are to follow.  */
+  
+  if (NUM_ELEM (documented_lang_options) > 1)
+    {
+      int       looking_for_start = 0;
+      
+      printf ("\nLanguage specific options:\n");
+
+      for (i = 0; i < NUM_ELEM (documented_lang_options); i++)
+       {
+         char * description = documented_lang_options[i].description;
+         char * option      = documented_lang_options[i].option;
+
+         if (description == NULL)
+           undoc = 1;
+         else if (* description == 0)
+           continue;
+         else if (option == NULL)
+           {
+             if (undoc)
+               printf
+                 ("\nThere are undocumented %s specific options as well.\n",
+                       lang);
+             undoc = 0;
+             
+             printf ("\n Options for %s:\n", description);
+
+             lang = description;
+           }
+         else
+           printf ("  %-23.23s %s\n", option, description);
+       }
+    }
+
+  if (undoc)
+    printf ("\nThere are undocumented %s specific options as well.\n", lang);
+
+  if (NUM_ELEM (target_switches) > 1
+#ifdef TARGET_OPTIONS
+      || NUM_ELEM (target_options) > 1
+#endif
+      )
+    {
+      int doc = 0;
+      
+      undoc = 0;
+  
+      printf ("\nTarget specific options:\n");
+
+      for (i = NUM_ELEM (target_switches); i--;)
+       {
+         char * option      = target_switches[i].name;
+         char * description = target_switches[i].description;
+
+         if (option == NULL)
+           continue;
+         else if (description == NULL)
+           undoc = 1;
+         else if (* description != 0)
+           doc += printf ("  %-23.23s %s\n", option, description);
+       }
+      
+#ifdef TARGET_OPTIONS      
+      for (i = NUM_ELEM (target_options); i--;)
+       {
+         char * option      = target_options[i].prefix;
+         char * description = target_options[i].description;
+
+         if (option == NULL)
+           continue;
+         else if (description == NULL)
+           undoc = 1;
+         else if (* description != 0)
+           doc += printf ("  %-23.23s %s\n", option, description);
+       }
+#endif
+      if (undoc)
+       if (doc)
+         printf ("\nThere are undocumented target specific options as well.\n");
+       else
+         printf ("  They exist, but they are not documented.\n");
+    }
+}
+
+/* Compare the user specified 'option' with the language
+   specific 'lang_option'.  Return true if they match, or
+   if 'option' is a viable prefix of 'lang_option'.  */
+
+static int
+check_lang_option (option, lang_option)
+     char * option;
+     char * lang_option;
+{
+  lang_independent_options * indep_options;
+  int    len;
+  long    k;
+
+  /* Ignore NULL entries.  */
+  if (option == NULL || lang_option == NULL)
+    return 0;
+
+  len = strlen (lang_option);
+
+  /* If they do not match to the first n characters then fail.  */
+  if (strncmp (option, lang_option, len) != 0)
+    return 0;
+         
+  /* Do not accept a lang option, if it matches a normal -f or -W
+     option.  Chill defines a -fpack, but we want to support
+     -fpack-struct.  */
+         
+  /* An exact match is OK  */
+  if (strlen (option) == len)
+    return 1;
+
+  /* If it is not an -f or -W option allow the match */
+  if (option[0] != '-')
+    return 1;
+
+  switch (option[1])
+    {
+    case 'f': indep_options = f_options; break;
+    case 'W': indep_options = W_options; break;
+    default:  return 1;
+    }
+
+  /* The option is a -f or -W option.
+     Skip past the prefix and search for the remainder in the
+     appropriate table of options.  */
+  option += 2;
+         
+  if (option[0] == 'n' && option[1] == 'o' && option[2] == '-')
+    option += 3;
+
+  for (k = NUM_ELEM (indep_options); k--;)
+    {
+      if (!strcmp (option, indep_options[k].string))
+       {
+         /* The option matched a language independent option,
+            do not allow the language specific match.  */
+
+         return 0;
+       }
+    }
+
+  /* The option matches the start of the langauge specific option
+     and it is not an exact match for a language independent option.  */
+  return 1;
+}
+\f
 /* Entry point of cc1/c++.  Decode command args, then call compile_file.
    Exit code is 35 if can't open files, 34 if fatal error,
    33 if had nonfatal errors, else success.  */
@@ -3914,13 +4306,14 @@ main (argc, argv, envp)
   for (i = 1; i < argc; i++)
     {
       size_t j;
+      
       /* If this is a language-specific option,
         decode it in a language-specific way.  */
-      for (j = 0; lang_options[j] != 0; j++)
-       if (!strncmp (argv[i], lang_options[j],
-                     strlen (lang_options[j])))
+      for (j = NUM_ELEM (documented_lang_options); j--;)
+       if (check_lang_option (argv[i], documented_lang_options[j].option))
          break;
-      if (lang_options[j] != 0)
+      
+      if (j != -1)
        {
          /* If the option is valid for *some* language,
             treat it as valid even if this language doesn't understand it.  */
@@ -4236,38 +4629,9 @@ main (argc, argv, envp)
                 -g and -ggdb don't explicitly set the debugging format so
                 -gdwarf -g3 is equivalent to -gdwarf3.  */
              static int type_explicitly_set_p = 0;
-             /* Table of supported debugging formats.  */
-             static struct {
-               char *arg;
-               /* Since PREFERRED_DEBUGGING_TYPE isn't necessarily a
-                  constant expression, we use NO_DEBUG in its place.  */
-               enum debug_info_type debug_type;
-               int use_extensions_p;
-             } *da, debug_args[] = {
-               { "g", NO_DEBUG, DEFAULT_GDB_EXTENSIONS },
-               { "ggdb", NO_DEBUG, 1 },
-#ifdef DBX_DEBUGGING_INFO
-               { "gstabs", DBX_DEBUG, 0 },
-               { "gstabs+", DBX_DEBUG, 1 },
-#endif
-#ifdef DWARF_DEBUGGING_INFO
-               { "gdwarf", DWARF_DEBUG, 0 },
-               { "gdwarf+", DWARF_DEBUG, 1 },
-#endif
-#ifdef DWARF2_DEBUGGING_INFO
-               { "gdwarf-2", DWARF2_DEBUG, 0 },
-#endif
-#ifdef XCOFF_DEBUGGING_INFO
-               { "gxcoff", XCOFF_DEBUG, 0 },
-               { "gxcoff+", XCOFF_DEBUG, 1 },
-#endif
-#ifdef SDB_DEBUGGING_INFO
-               { "gcoff", SDB_DEBUG, 0 },
-#endif
-               { 0, 0, 0 }
-             };
              /* Indexed by enum debug_info_type.  */
-             static char *debug_type_names[] = {
+             static char *debug_type_names[] =
+             {
                "none", "stabs", "coff", "dwarf-1", "dwarf-2", "xcoff"
              };
 
@@ -4374,6 +4738,11 @@ main (argc, argv, envp)
              flag_gen_aux_info = 1;
              aux_info_file_name = (str[8] != '\0' ? str+8 : argv[++i]);
            }
+         else if (!strcmp (str, "-help"))
+           {
+             display_help ();
+             exit (0);
+           }
          else
            error ("Invalid option `%s'", argv[i]);
        }
@@ -4483,23 +4852,6 @@ main (argc, argv, envp)
 }
 \f
 /* Decode -m switches.  */
-
-/* Here is a table, controlled by the tm.h file, listing each -m switch
-   and which bits in `target_switches' it should set or clear.
-   If VALUE is positive, it is bits to set.
-   If VALUE is negative, -VALUE is bits to clear.
-   (The sign bit is not used so there is no confusion.)  */
-
-struct {char *name; int value;} target_switches []
-  = TARGET_SWITCHES;
-
-/* This table is similar, but allows the switch to have a value.  */
-
-#ifdef TARGET_OPTIONS
-struct {char *prefix; char ** variable;} target_options []
-  = TARGET_OPTIONS;
-#endif
-
 /* Decode the switch -mNAME.  */
 
 void