Postpone print of --help=* option.
authorMartin Liska <mliska@suse.cz>
Thu, 2 May 2019 08:16:12 +0000 (10:16 +0200)
committerMartin Liska <marxin@gcc.gnu.org>
Thu, 2 May 2019 08:16:12 +0000 (08:16 +0000)
2019-05-02  Martin Liska  <mliska@suse.cz>

* gcc.c (process_command): Add dummy file only
if n_infiles == 0.
* opts-global.c (decode_options): Pass lang_mask.
* opts.c (print_help): New function.
(finish_options): Print --help if help_option_argument
is set.
(common_handle_option): Factor out content of OPT__help_
into print_help.
* opts.h (finish_options): Add new argument.

From-SVN: r270788

gcc/ChangeLog
gcc/gcc.c
gcc/opts-global.c
gcc/opts.c
gcc/opts.h

index 1883e4df91ff7d3959cf4e17df00f81b6fa82d4f..a6ce52335d5de2bb187de434c008a4ee3435a2be 100644 (file)
@@ -1,3 +1,15 @@
+2019-05-02  Martin Liska  <mliska@suse.cz>
+
+       * gcc.c (process_command): Add dummy file only
+       if n_infiles == 0.
+       * opts-global.c (decode_options): Pass lang_mask.
+       * opts.c (print_help): New function.
+       (finish_options): Print --help if help_option_argument
+       is set.
+       (common_handle_option): Factor out content of OPT__help_
+       into print_help.
+       * opts.h (finish_options): Add new argument.
+
 2019-05-02  Martin Liska  <mliska@suse.cz>
 
        PR target/88809
index 4f57765b012ae07bd0c44ba740d439f965af3379..a1003a5cdf93affa0c345c6f61606d4e2edd4624 100644 (file)
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -4751,10 +4751,9 @@ process_command (unsigned int decoded_options_count,
     }
 
   /* Ensure we only invoke each subprocess once.  */
-  if (print_subprocess_help || print_help_list || print_version)
+  if (n_infiles == 0
+      && (print_subprocess_help || print_help_list || print_version))
     {
-      n_infiles = 0;
-
       /* Create a dummy input file, so that we can pass
         the help option on to the various sub-processes.  */
       add_infile ("help-dummy", "c");
index a5e9ef0237aac6fe191e2f4e68929ba6b8c4eeb9..f110fe1026fb87c5bdd8f7c104946c1f3c6e008f 100644 (file)
@@ -314,7 +314,7 @@ decode_options (struct gcc_options *opts, struct gcc_options *opts_set,
                        loc, lang_mask,
                        &handlers, dc);
 
-  finish_options (opts, opts_set, loc);
+  finish_options (opts, opts_set, loc, lang_mask);
 }
 
 /* Hold command-line options associated with stack limitation.  */
index 926904c609e64c25d7bb7194e0af085668dac2c7..286bb8f5402bc2e07119e29c9b53284dd5196bd1 100644 (file)
@@ -855,12 +855,18 @@ control_options_for_live_patching (struct gcc_options *opts,
     }
 }
 
+/* --help option argument if set.  */
+const char *help_option_argument = NULL;
+
+static void print_help (struct gcc_options *opts, unsigned int lang_mask);
+
+
 /* After all options at LOC have been read into OPTS and OPTS_SET,
    finalize settings of those options and diagnose incompatible
    combinations.  */
 void
 finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
-               location_t loc)
+               location_t loc, unsigned int lang_mask)
 {
   enum unwind_info_type ui_except;
 
@@ -1224,6 +1230,10 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
                                         opts->x_flag_live_patching,
                                         loc);
     }
+
+  /* Print --help=* if used.  */
+  if (help_option_argument != NULL)
+    print_help (opts, lang_mask);
 }
 
 #define LEFT_COLUMN    27
@@ -2054,6 +2064,135 @@ check_alignment_argument (location_t loc, const char *flag, const char *name)
   parse_and_check_align_values (flag, name, align_result, true, loc);
 }
 
+/* Print help when OPT__help_ is set.  */
+
+static void
+print_help (struct gcc_options *opts, unsigned int lang_mask)
+{
+  const char *a = help_option_argument;
+  unsigned int include_flags = 0;
+  /* Note - by default we include undocumented options when listing
+     specific classes.  If you only want to see documented options
+     then add ",^undocumented" to the --help= option.  E.g.:
+
+     --help=target,^undocumented  */
+  unsigned int exclude_flags = 0;
+
+  if (lang_mask == CL_DRIVER)
+    return;
+
+  /* Walk along the argument string, parsing each word in turn.
+     The format is:
+     arg = [^]{word}[,{arg}]
+     word = {optimizers|target|warnings|undocumented|
+     params|common|<language>}  */
+  while (*a != 0)
+    {
+      static const struct
+       {
+         const char *string;
+         unsigned int flag;
+       }
+      specifics[] =
+       {
+           { "optimizers", CL_OPTIMIZATION },
+           { "target", CL_TARGET },
+           { "warnings", CL_WARNING },
+           { "undocumented", CL_UNDOCUMENTED },
+           { "params", CL_PARAMS },
+           { "joined", CL_JOINED },
+           { "separate", CL_SEPARATE },
+           { "common", CL_COMMON },
+           { NULL, 0 }
+       };
+      unsigned int *pflags;
+      const char *comma;
+      unsigned int lang_flag, specific_flag;
+      unsigned int len;
+      unsigned int i;
+
+      if (*a == '^')
+       {
+         ++a;
+         if (*a == '\0')
+           {
+             error ("missing argument to %qs", "--help=^");
+             break;
+           }
+         pflags = &exclude_flags;
+       }
+      else
+       pflags = &include_flags;
+
+      comma = strchr (a, ',');
+      if (comma == NULL)
+       len = strlen (a);
+      else
+       len = comma - a;
+      if (len == 0)
+       {
+         a = comma + 1;
+         continue;
+       }
+
+      /* Check to see if the string matches an option class name.  */
+      for (i = 0, specific_flag = 0; specifics[i].string != NULL; i++)
+       if (strncasecmp (a, specifics[i].string, len) == 0)
+         {
+           specific_flag = specifics[i].flag;
+           break;
+         }
+
+      /* Check to see if the string matches a language name.
+        Note - we rely upon the alpha-sorted nature of the entries in
+        the lang_names array, specifically that shorter names appear
+        before their longer variants.  (i.e. C before C++).  That way
+        when we are attempting to match --help=c for example we will
+        match with C first and not C++.  */
+      for (i = 0, lang_flag = 0; i < cl_lang_count; i++)
+       if (strncasecmp (a, lang_names[i], len) == 0)
+         {
+           lang_flag = 1U << i;
+           break;
+         }
+
+      if (specific_flag != 0)
+       {
+         if (lang_flag == 0)
+           *pflags |= specific_flag;
+         else
+           {
+             /* The option's argument matches both the start of a
+                language name and the start of an option class name.
+                We have a special case for when the user has
+                specified "--help=c", but otherwise we have to issue
+                a warning.  */
+             if (strncasecmp (a, "c", len) == 0)
+               *pflags |= lang_flag;
+             else
+               warning (0,
+                        "--help argument %q.*s is ambiguous, "
+                        "please be more specific",
+                        len, a);
+           }
+       }
+      else if (lang_flag != 0)
+       *pflags |= lang_flag;
+      else
+       warning (0,
+                "unrecognized argument to --help= option: %q.*s",
+                len, a);
+
+      if (comma == NULL)
+       break;
+      a = comma + 1;
+    }
+
+  if (include_flags)
+    print_specific_help (include_flags, exclude_flags, 0, opts,
+                        lang_mask);
+}
+
 /* Handle target- and language-independent options.  Return zero to
    generate an "unknown option" message.  Only options that need
    extra handling need to be listed here; if you simply want
@@ -2121,131 +2260,7 @@ common_handle_option (struct gcc_options *opts,
 
     case OPT__help_:
       {
-       const char *a = arg;
-       unsigned int include_flags = 0;
-       /* Note - by default we include undocumented options when listing
-          specific classes.  If you only want to see documented options
-          then add ",^undocumented" to the --help= option.  E.g.:
-
-          --help=target,^undocumented  */
-       unsigned int exclude_flags = 0;
-
-       if (lang_mask == CL_DRIVER)
-         break;
-
-       /* Walk along the argument string, parsing each word in turn.
-          The format is:
-          arg = [^]{word}[,{arg}]
-          word = {optimizers|target|warnings|undocumented|
-                  params|common|<language>}  */
-       while (*a != 0)
-         {
-           static const struct
-           {
-             const char *string;
-             unsigned int flag;
-           }
-           specifics[] =
-           {
-             { "optimizers", CL_OPTIMIZATION },
-             { "target", CL_TARGET },
-             { "warnings", CL_WARNING },
-             { "undocumented", CL_UNDOCUMENTED },
-             { "params", CL_PARAMS },
-             { "joined", CL_JOINED },
-             { "separate", CL_SEPARATE },
-             { "common", CL_COMMON },
-             { NULL, 0 }
-           };
-           unsigned int *pflags;
-           const char *comma;
-           unsigned int lang_flag, specific_flag;
-           unsigned int len;
-           unsigned int i;
-
-           if (*a == '^')
-             {
-               ++a;
-               if (*a == '\0')
-                 {
-                   error_at (loc, "missing argument to %qs", "--help=^");
-                   break;
-                 }
-               pflags = &exclude_flags;
-             }
-           else
-             pflags = &include_flags;
-
-           comma = strchr (a, ',');
-           if (comma == NULL)
-             len = strlen (a);
-           else
-             len = comma - a;
-           if (len == 0)
-             {
-               a = comma + 1;
-               continue;
-             }
-
-           /* Check to see if the string matches an option class name.  */
-           for (i = 0, specific_flag = 0; specifics[i].string != NULL; i++)
-             if (strncasecmp (a, specifics[i].string, len) == 0)
-               {
-                 specific_flag = specifics[i].flag;
-                 break;
-               }
-
-           /* Check to see if the string matches a language name.
-              Note - we rely upon the alpha-sorted nature of the entries in
-              the lang_names array, specifically that shorter names appear
-              before their longer variants.  (i.e. C before C++).  That way
-              when we are attempting to match --help=c for example we will
-              match with C first and not C++.  */
-           for (i = 0, lang_flag = 0; i < cl_lang_count; i++)
-             if (strncasecmp (a, lang_names[i], len) == 0)
-               {
-                 lang_flag = 1U << i;
-                 break;
-               }
-
-           if (specific_flag != 0)
-             {
-               if (lang_flag == 0)
-                 *pflags |= specific_flag;
-               else
-                 {
-                   /* The option's argument matches both the start of a
-                      language name and the start of an option class name.
-                      We have a special case for when the user has
-                      specified "--help=c", but otherwise we have to issue
-                      a warning.  */
-                   if (strncasecmp (a, "c", len) == 0)
-                     *pflags |= lang_flag;
-                   else
-                     warning_at (loc, 0,
-                                 "--help argument %q.*s is ambiguous, "
-                                 "please be more specific",
-                                 len, a);
-                 }
-             }
-           else if (lang_flag != 0)
-             *pflags |= lang_flag;
-           else
-             warning_at (loc, 0,
-                         "unrecognized argument to --help= option: %q.*s",
-                         len, a);
-
-           if (comma == NULL)
-             break;
-           a = comma + 1;
-         }
-
-       if (include_flags)
-         {
-           target_option_override_hook ();
-           print_specific_help (include_flags, exclude_flags, 0, opts,
-                                lang_mask);
-         }
+       help_option_argument = arg;
        opts->x_exit_after_options = true;
        break;
       }
index f14d9bcb896cc843f2bc4336630cc67a2395e853..6e99eaddbaf5e81a12bb11b1464310d8e9857eb9 100644 (file)
@@ -418,7 +418,8 @@ extern bool target_handle_option (struct gcc_options *opts,
                                  void (*target_option_override_hook) (void));
 extern void finish_options (struct gcc_options *opts,
                            struct gcc_options *opts_set,
-                           location_t loc);
+                           location_t loc,
+                           unsigned int lang_mask);
 extern void default_options_optimization (struct gcc_options *opts,
                                          struct gcc_options *opts_set,
                                          struct cl_decoded_option *decoded_options,