diff --git a/gcc/opts.c b/gcc/opts.c index f159bb35130..df5e2462d76 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -1815,7 +1815,9 @@ print_specific_help (unsigned int include_flags, { if (any_flags == 0) { - if (include_flags & CL_UNDOCUMENTED) + if (include_flags & CL_DRIVER) + description = _("The following options control the driver"); + else if (include_flags & CL_UNDOCUMENTED) description = _("The following options are not documented"); else if (include_flags & CL_SEPARATE) description = _("The following options take separate arguments"); @@ -2276,30 +2278,38 @@ print_help (struct gcc_options *opts, unsigned int lang_mask, if (lang_mask == CL_DRIVER) return; + static const struct + { + const char *string; + unsigned int flag; + } + specifics[] = + { + { "common", CL_COMMON }, + { "driver", CL_DRIVER }, + { "joined", CL_JOINED }, + { "optimizers", CL_OPTIMIZATION }, + { "params", CL_PARAMS }, + { "separate", CL_SEPARATE }, + { "target", CL_TARGET }, + { "undocumented", CL_UNDOCUMENTED }, + { "warnings", CL_WARNING }, + { NULL, 0 } + }; + + auto_vec candidates; + for (unsigned int i = 0; specifics[i].string != NULL; i++) + candidates.safe_push (specifics[i].string); + for (unsigned int i = 0; i < cl_lang_count; i++) + candidates.safe_push (lang_names[i]); + /* Walk along the argument string, parsing each word in turn. The format is: arg = [^]{word}[,{arg}] - word = {optimizers|target|warnings|undocumented| - params|common|} */ + word = {common|driver|joined|optimizers|params|separate + |target|undocumented|warnings|} */ 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; @@ -2311,7 +2321,11 @@ print_help (struct gcc_options *opts, unsigned int lang_mask, ++a; if (*a == '\0') { + char *s; error ("missing argument to %qs", "--help=^"); + candidates_list_and_hint ("", s, candidates); + inform (UNKNOWN_LOCATION, "valid arguments to %qs are: %s", "--help=^", s); + XDELETEVEC (s); break; } pflags = &exclude_flags; @@ -2365,18 +2379,38 @@ print_help (struct gcc_options *opts, unsigned int lang_mask, if (strncasecmp (a, "c", len) == 0) *pflags |= lang_flag; else - warning (0, - "%<--help%> argument %q.*s is ambiguous, " - "please be more specific", - len, a); + { + char *s; + warning (0, + "%<--help%> argument %q.*s is ambiguous, " + "please be more specific", + len, a); + candidates_list_and_hint ("", s, candidates); + inform (UNKNOWN_LOCATION, + "valid arguments to %qs are: %s", "--help=", s); + XDELETEVEC (s); + } } } else if (lang_flag != 0) *pflags |= lang_flag; else - warning (0, - "unrecognized argument to %<--help=%> option: %q.*s", - len, a); + { + char *s; + char *arg = XALLOCAVEC (char, len + 1); + memcpy (arg, a, len); + arg[len] = '\0'; + warning (0, "unrecognized argument to %<--help=%> option: %qs", arg); + const char *hint = candidates_list_and_hint (arg, s, candidates); + if (hint) + inform (UNKNOWN_LOCATION, + "valid arguments to %qs are: %s; did you mean %qs?", + "--help", s, hint); + else + inform (UNKNOWN_LOCATION, + "valid arguments to %qs are: %s", "--help=", s); + XDELETEVEC (s); + } if (comma == NULL) break;