diff options
author | Olivier Hainque <hainque@adacore.com> | 2018-07-31 09:44:48 +0000 |
---|---|---|
committer | Olivier Hainque <hainque@gcc.gnu.org> | 2018-07-31 09:44:48 +0000 |
commit | 1102fd64dbb76784ed46ff81bf905f6c52d296fc (patch) | |
tree | 01df7b448b42224660ce88c2de17c35bbc6c75f2 /gcc/gcc.c | |
parent | f37866e818ab839e0db68be23e5a339e5e7c19dc (diff) | |
download | gcc-1102fd64dbb76784ed46ff81bf905f6c52d296fc.zip gcc-1102fd64dbb76784ed46ff81bf905f6c52d296fc.tar.gz gcc-1102fd64dbb76784ed46ff81bf905f6c52d296fc.tar.bz2 |
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
Diffstat (limited to 'gcc/gcc.c')
-rw-r--r-- | gcc/gcc.c | 51 |
1 files changed, 29 insertions, 22 deletions
@@ -355,12 +355,12 @@ static inline void mark_matching_switches (const char *, const char *, int); static inline void process_marked_switches (void); 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 char *eval_spec_function (const char *, const char *); -static const char *handle_spec_function (const char *, bool *); +static const char *eval_spec_function (const char *, const char *, const char *); +static const char *handle_spec_function (const char *, bool *, const char *); static char *save_string (const char *, int); static void set_collect_gcc_options (void); 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_self_spec (const char *); static const char *find_file (const char *); @@ -4939,7 +4939,7 @@ do_spec (const char *spec) { int value; - value = do_spec_2 (spec); + value = do_spec_2 (spec, NULL); /* Force out any unfinished command. If -pipe, this forces out the last command if it ended in `|'. */ @@ -4958,8 +4958,11 @@ do_spec (const char *spec) 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 -do_spec_2 (const char *spec) +do_spec_2 (const char *spec, const char *soft_matched_part) { int result; @@ -4972,14 +4975,13 @@ do_spec_2 (const char *spec) input_from_pipe = 0; suffix_subst = NULL; - result = do_spec_1 (spec, 0, NULL); + result = do_spec_1 (spec, 0, soft_matched_part); end_going_arg (); return result; } - /* Process the given spec string and add any new options to the end of the switches/n_switches array. */ @@ -5037,7 +5039,7 @@ do_self_spec (const char *spec) { int i; - do_spec_2 (spec); + do_spec_2 (spec, NULL); do_spec_1 (" ", 0, NULL); /* 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) break; case ':': - p = handle_spec_function (p, NULL); + p = handle_spec_function (p, NULL, soft_matched_part); if (p == 0) return -1; break; @@ -6039,7 +6041,8 @@ lookup_spec_function (const char *name) /* Evaluate a spec function. */ 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 char *funcval; @@ -6089,7 +6092,7 @@ eval_spec_function (const char *func, const char *args) arguments. */ 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); /* 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) NULL if no processing is required. 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 * -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; const char *endp, *funcval; @@ -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. */ - 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) p = NULL; if (retval_nonnull) @@ -6326,7 +6333,7 @@ handle_braces (const char *p) { atom = NULL; end_atom = NULL; - p = handle_spec_function (p + 2, &a_matched); + p = handle_spec_function (p + 2, &a_matched, NULL); } else { @@ -7561,7 +7568,7 @@ driver::set_up_specs () const /* Process sysroot_suffix_spec. */ if (*sysroot_suffix_spec != 0 && !no_sysroot_suffix - && do_spec_2 (sysroot_suffix_spec) == 0) + && do_spec_2 (sysroot_suffix_spec, NULL) == 0) { if (argbuf.length () > 1) error ("spec failure: more than one arg to SYSROOT_SUFFIX_SPEC"); @@ -7585,7 +7592,7 @@ driver::set_up_specs () const /* Process sysroot_hdrs_suffix_spec. */ if (*sysroot_hdrs_suffix_spec != 0 && !no_sysroot_suffix - && do_spec_2 (sysroot_hdrs_suffix_spec) == 0) + && do_spec_2 (sysroot_hdrs_suffix_spec, NULL) == 0) { if (argbuf.length () > 1) error ("spec failure: more than one arg to SYSROOT_HEADERS_SUFFIX_SPEC"); @@ -7595,7 +7602,7 @@ driver::set_up_specs () const /* Look for startfiles in the standard places. */ 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) { const char *arg; @@ -9640,7 +9647,7 @@ compare_debug_dump_opt_spec_function (int arg, fatal_error (input_location, "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); if (argbuf.length () > 0 @@ -9658,13 +9665,13 @@ compare_debug_dump_opt_spec_function (int arg, 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"; } else if (!compare_debug) return NULL; else - do_spec_2 ("%g.gkd"); + do_spec_2 ("%g.gkd", NULL); do_spec_1 (" ", 0, NULL); @@ -9716,7 +9723,7 @@ compare_debug_self_opt_spec_function (int arg, if (compare_debug >= 0) return NULL; - do_spec_2 ("%{c|S:%{o*:%*}}"); + do_spec_2 ("%{c|S:%{o*:%*}}", NULL); do_spec_1 (" ", 0, NULL); if (argbuf.length () > 0) |