Postpone print of --help=* option.

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
This commit is contained in:
Martin Liska 2019-05-02 10:16:12 +02:00 committed by Martin Liska
parent 786e0e5239
commit 2dcfc8722b
5 changed files with 158 additions and 131 deletions

View 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> 2019-05-02 Martin Liska <mliska@suse.cz>
PR target/88809 PR target/88809

View File

@ -4751,10 +4751,9 @@ process_command (unsigned int decoded_options_count,
} }
/* Ensure we only invoke each subprocess once. */ /* 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 /* Create a dummy input file, so that we can pass
the help option on to the various sub-processes. */ the help option on to the various sub-processes. */
add_infile ("help-dummy", "c"); add_infile ("help-dummy", "c");

View File

@ -314,7 +314,7 @@ decode_options (struct gcc_options *opts, struct gcc_options *opts_set,
loc, lang_mask, loc, lang_mask,
&handlers, dc); &handlers, dc);
finish_options (opts, opts_set, loc); finish_options (opts, opts_set, loc, lang_mask);
} }
/* Hold command-line options associated with stack limitation. */ /* Hold command-line options associated with stack limitation. */

View 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, /* After all options at LOC have been read into OPTS and OPTS_SET,
finalize settings of those options and diagnose incompatible finalize settings of those options and diagnose incompatible
combinations. */ combinations. */
void void
finish_options (struct gcc_options *opts, struct gcc_options *opts_set, 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; 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, opts->x_flag_live_patching,
loc); loc);
} }
/* Print --help=* if used. */
if (help_option_argument != NULL)
print_help (opts, lang_mask);
} }
#define LEFT_COLUMN 27 #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); 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 /* Handle target- and language-independent options. Return zero to
generate an "unknown option" message. Only options that need generate an "unknown option" message. Only options that need
extra handling need to be listed here; if you simply want 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_: case OPT__help_:
{ {
const char *a = arg; help_option_argument = 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);
}
opts->x_exit_after_options = true; opts->x_exit_after_options = true;
break; break;
} }

View File

@ -418,7 +418,8 @@ extern bool target_handle_option (struct gcc_options *opts,
void (*target_option_override_hook) (void)); void (*target_option_override_hook) (void));
extern void finish_options (struct gcc_options *opts, extern void finish_options (struct gcc_options *opts,
struct gcc_options *opts_set, struct gcc_options *opts_set,
location_t loc); location_t loc,
unsigned int lang_mask);
extern void default_options_optimization (struct gcc_options *opts, extern void default_options_optimization (struct gcc_options *opts,
struct gcc_options *opts_set, struct gcc_options *opts_set,
struct cl_decoded_option *decoded_options, struct cl_decoded_option *decoded_options,