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:
parent
786e0e5239
commit
2dcfc8722b
@ -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
|
||||
|
@ -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");
|
||||
|
@ -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. */
|
||||
|
267
gcc/opts.c
267
gcc/opts.c
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user