Commit 1102fd64 by Olivier Hainque Committed by Olivier Hainque

Improve specs processing to allow %* in function arguments

2018-07-31  Olivier Hainque  <hainque@adacore.com>

	* gcc.c (handle_spec_function): Accept a soft_matched_part
	argument, as do_spec_1.  Pass it down to ...
	(eval_spec_function): Accept a soft_matched_part argument,
	and pass it down to ...
	(do_spec_2): Accept a soft_matched_part argument, and pass
	it down to do_spec_1.
	(do_spec_1): Pass soft_matched_part to handle_spec_function.
	(handle_braces): Update call to handle_spec_function.
	(driver::set_up_specs): Update calls to do_spec_2.
	(compare_debug_dump_opt_spec_function): Likewise.
	(compare_debug_self_opt_spec_function): Likewise.

From-SVN: r263087
parent f37866e8
2018-07-31 Olivier Hainque <hainque@adacore.com> 2018-07-31 Olivier Hainque <hainque@adacore.com>
* gcc.c (handle_spec_function): Accept a soft_matched_part
argument, as do_spec_1. Pass it down to ...
(eval_spec_function): Accept a soft_matched_part argument,
and pass it down to ...
(do_spec_2): Accept a soft_matched_part argument, and pass
it down to do_spec_1.
(do_spec_1): Pass soft_matched_part to handle_spec_function.
(handle_braces): Update call to handle_spec_function.
(driver::set_up_specs): Update calls to do_spec_2.
(compare_debug_dump_opt_spec_function): Likewise.
(compare_debug_self_opt_spec_function): Likewise.
2018-07-31 Olivier Hainque <hainque@adacore.com>
* common.opt (nolibc): New option. * common.opt (nolibc): New option.
* doc/invoke.texi (Link Options): Document it. * doc/invoke.texi (Link Options): Document it.
* gcc.c (LINK_GCC_C_SEQUENCE_SPEC): Honor nolibc. * gcc.c (LINK_GCC_C_SEQUENCE_SPEC): Honor nolibc.
......
...@@ -355,12 +355,12 @@ static inline void mark_matching_switches (const char *, const char *, int); ...@@ -355,12 +355,12 @@ static inline void mark_matching_switches (const char *, const char *, int);
static inline void process_marked_switches (void); static inline void process_marked_switches (void);
static const char *process_brace_body (const char *, const char *, const char *, int, int); static const char *process_brace_body (const char *, const char *, const char *, int, int);
static const struct spec_function *lookup_spec_function (const char *); static const struct spec_function *lookup_spec_function (const char *);
static const char *eval_spec_function (const char *, const char *); static const char *eval_spec_function (const char *, const char *, const char *);
static const char *handle_spec_function (const char *, bool *); static const char *handle_spec_function (const char *, bool *, const char *);
static char *save_string (const char *, int); static char *save_string (const char *, int);
static void set_collect_gcc_options (void); static void set_collect_gcc_options (void);
static int do_spec_1 (const char *, int, const char *); static int do_spec_1 (const char *, int, const char *);
static int do_spec_2 (const char *); static int do_spec_2 (const char *, const char *);
static void do_option_spec (const char *, const char *); static void do_option_spec (const char *, const char *);
static void do_self_spec (const char *); static void do_self_spec (const char *);
static const char *find_file (const char *); static const char *find_file (const char *);
...@@ -4939,7 +4939,7 @@ do_spec (const char *spec) ...@@ -4939,7 +4939,7 @@ do_spec (const char *spec)
{ {
int value; int value;
value = do_spec_2 (spec); value = do_spec_2 (spec, NULL);
/* Force out any unfinished command. /* Force out any unfinished command.
If -pipe, this forces out the last command if it ended in `|'. */ If -pipe, this forces out the last command if it ended in `|'. */
...@@ -4958,8 +4958,11 @@ do_spec (const char *spec) ...@@ -4958,8 +4958,11 @@ do_spec (const char *spec)
return value; return value;
} }
/* Process the spec SPEC, with SOFT_MATCHED_PART designating the current value
of a matched * pattern which may be re-injected by way of %*. */
static int static int
do_spec_2 (const char *spec) do_spec_2 (const char *spec, const char *soft_matched_part)
{ {
int result; int result;
...@@ -4972,14 +4975,13 @@ do_spec_2 (const char *spec) ...@@ -4972,14 +4975,13 @@ do_spec_2 (const char *spec)
input_from_pipe = 0; input_from_pipe = 0;
suffix_subst = NULL; suffix_subst = NULL;
result = do_spec_1 (spec, 0, NULL); result = do_spec_1 (spec, 0, soft_matched_part);
end_going_arg (); end_going_arg ();
return result; return result;
} }
/* Process the given spec string and add any new options to the end /* Process the given spec string and add any new options to the end
of the switches/n_switches array. */ of the switches/n_switches array. */
...@@ -5037,7 +5039,7 @@ do_self_spec (const char *spec) ...@@ -5037,7 +5039,7 @@ do_self_spec (const char *spec)
{ {
int i; int i;
do_spec_2 (spec); do_spec_2 (spec, NULL);
do_spec_1 (" ", 0, NULL); do_spec_1 (" ", 0, NULL);
/* Mark %<S switches processed by do_self_spec to be ignored permanently. /* Mark %<S switches processed by do_self_spec to be ignored permanently.
...@@ -5877,7 +5879,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) ...@@ -5877,7 +5879,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
break; break;
case ':': case ':':
p = handle_spec_function (p, NULL); p = handle_spec_function (p, NULL, soft_matched_part);
if (p == 0) if (p == 0)
return -1; return -1;
break; break;
...@@ -6039,7 +6041,8 @@ lookup_spec_function (const char *name) ...@@ -6039,7 +6041,8 @@ lookup_spec_function (const char *name)
/* Evaluate a spec function. */ /* Evaluate a spec function. */
static const char * static const char *
eval_spec_function (const char *func, const char *args) eval_spec_function (const char *func, const char *args,
const char *soft_matched_part)
{ {
const struct spec_function *sf; const struct spec_function *sf;
const char *funcval; const char *funcval;
...@@ -6089,7 +6092,7 @@ eval_spec_function (const char *func, const char *args) ...@@ -6089,7 +6092,7 @@ eval_spec_function (const char *func, const char *args)
arguments. */ arguments. */
alloc_args (); alloc_args ();
if (do_spec_2 (args) < 0) if (do_spec_2 (args, soft_matched_part) < 0)
fatal_error (input_location, "error in args to spec function %qs", func); fatal_error (input_location, "error in args to spec function %qs", func);
/* argbuf_index is an index for the next argument to be inserted, and /* argbuf_index is an index for the next argument to be inserted, and
...@@ -6126,10 +6129,14 @@ eval_spec_function (const char *func, const char *args) ...@@ -6126,10 +6129,14 @@ eval_spec_function (const char *func, const char *args)
NULL if no processing is required. NULL if no processing is required.
If RETVAL_NONNULL is not NULL, then store a bool whether function If RETVAL_NONNULL is not NULL, then store a bool whether function
returned non-NULL. */ returned non-NULL.
SOFT_MATCHED_PART holds the current value of a matched * pattern, which
may be re-expanded with a %* as part of the function arguments. */
static const char * static const char *
handle_spec_function (const char *p, bool *retval_nonnull) handle_spec_function (const char *p, bool *retval_nonnull,
const char *soft_matched_part)
{ {
char *func, *args; char *func, *args;
const char *endp, *funcval; const char *endp, *funcval;
...@@ -6172,7 +6179,7 @@ handle_spec_function (const char *p, bool *retval_nonnull) ...@@ -6172,7 +6179,7 @@ handle_spec_function (const char *p, bool *retval_nonnull)
/* p now points to just past the end of the spec function expression. */ /* p now points to just past the end of the spec function expression. */
funcval = eval_spec_function (func, args); funcval = eval_spec_function (func, args, soft_matched_part);
if (funcval != NULL && do_spec_1 (funcval, 0, NULL) < 0) if (funcval != NULL && do_spec_1 (funcval, 0, NULL) < 0)
p = NULL; p = NULL;
if (retval_nonnull) if (retval_nonnull)
...@@ -6326,7 +6333,7 @@ handle_braces (const char *p) ...@@ -6326,7 +6333,7 @@ handle_braces (const char *p)
{ {
atom = NULL; atom = NULL;
end_atom = NULL; end_atom = NULL;
p = handle_spec_function (p + 2, &a_matched); p = handle_spec_function (p + 2, &a_matched, NULL);
} }
else else
{ {
...@@ -7561,7 +7568,7 @@ driver::set_up_specs () const ...@@ -7561,7 +7568,7 @@ driver::set_up_specs () const
/* Process sysroot_suffix_spec. */ /* Process sysroot_suffix_spec. */
if (*sysroot_suffix_spec != 0 if (*sysroot_suffix_spec != 0
&& !no_sysroot_suffix && !no_sysroot_suffix
&& do_spec_2 (sysroot_suffix_spec) == 0) && do_spec_2 (sysroot_suffix_spec, NULL) == 0)
{ {
if (argbuf.length () > 1) if (argbuf.length () > 1)
error ("spec failure: more than one arg to SYSROOT_SUFFIX_SPEC"); error ("spec failure: more than one arg to SYSROOT_SUFFIX_SPEC");
...@@ -7585,7 +7592,7 @@ driver::set_up_specs () const ...@@ -7585,7 +7592,7 @@ driver::set_up_specs () const
/* Process sysroot_hdrs_suffix_spec. */ /* Process sysroot_hdrs_suffix_spec. */
if (*sysroot_hdrs_suffix_spec != 0 if (*sysroot_hdrs_suffix_spec != 0
&& !no_sysroot_suffix && !no_sysroot_suffix
&& do_spec_2 (sysroot_hdrs_suffix_spec) == 0) && do_spec_2 (sysroot_hdrs_suffix_spec, NULL) == 0)
{ {
if (argbuf.length () > 1) if (argbuf.length () > 1)
error ("spec failure: more than one arg to SYSROOT_HEADERS_SUFFIX_SPEC"); error ("spec failure: more than one arg to SYSROOT_HEADERS_SUFFIX_SPEC");
...@@ -7595,7 +7602,7 @@ driver::set_up_specs () const ...@@ -7595,7 +7602,7 @@ driver::set_up_specs () const
/* Look for startfiles in the standard places. */ /* Look for startfiles in the standard places. */
if (*startfile_prefix_spec != 0 if (*startfile_prefix_spec != 0
&& do_spec_2 (startfile_prefix_spec) == 0 && do_spec_2 (startfile_prefix_spec, NULL) == 0
&& do_spec_1 (" ", 0, NULL) == 0) && do_spec_1 (" ", 0, NULL) == 0)
{ {
const char *arg; const char *arg;
...@@ -9640,7 +9647,7 @@ compare_debug_dump_opt_spec_function (int arg, ...@@ -9640,7 +9647,7 @@ compare_debug_dump_opt_spec_function (int arg,
fatal_error (input_location, fatal_error (input_location,
"too many arguments to %%:compare-debug-dump-opt"); "too many arguments to %%:compare-debug-dump-opt");
do_spec_2 ("%{fdump-final-insns=*:%*}"); do_spec_2 ("%{fdump-final-insns=*:%*}", NULL);
do_spec_1 (" ", 0, NULL); do_spec_1 (" ", 0, NULL);
if (argbuf.length () > 0 if (argbuf.length () > 0
...@@ -9658,13 +9665,13 @@ compare_debug_dump_opt_spec_function (int arg, ...@@ -9658,13 +9665,13 @@ compare_debug_dump_opt_spec_function (int arg,
if (argbuf.length () > 0) if (argbuf.length () > 0)
{ {
do_spec_2 ("%{o*:%*}%{!o:%{!S:%b%O}%{S:%b.s}}"); do_spec_2 ("%{o*:%*}%{!o:%{!S:%b%O}%{S:%b.s}}", NULL);
ext = ".gkd"; ext = ".gkd";
} }
else if (!compare_debug) else if (!compare_debug)
return NULL; return NULL;
else else
do_spec_2 ("%g.gkd"); do_spec_2 ("%g.gkd", NULL);
do_spec_1 (" ", 0, NULL); do_spec_1 (" ", 0, NULL);
...@@ -9716,7 +9723,7 @@ compare_debug_self_opt_spec_function (int arg, ...@@ -9716,7 +9723,7 @@ compare_debug_self_opt_spec_function (int arg,
if (compare_debug >= 0) if (compare_debug >= 0)
return NULL; return NULL;
do_spec_2 ("%{c|S:%{o*:%*}}"); do_spec_2 ("%{c|S:%{o*:%*}}", NULL);
do_spec_1 (" ", 0, NULL); do_spec_1 (" ", 0, NULL);
if (argbuf.length () > 0) if (argbuf.length () > 0)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment