Improve specs processing to allow %* in function arguments
authorOlivier Hainque <hainque@adacore.com>
Tue, 31 Jul 2018 09:44:48 +0000 (09:44 +0000)
committerOlivier Hainque <hainque@gcc.gnu.org>
Tue, 31 Jul 2018 09:44:48 +0000 (09:44 +0000)
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

gcc/ChangeLog
gcc/gcc.c

index cb0fb088548fa628862ab000d528f06a177a83b1..3237566b91a4980056f1e80daa8d5d28994cb917 100644 (file)
@@ -1,3 +1,17 @@
+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.
index da91112be5e1d8959c85383f78bdd275a9718849..780d4859ef33e4d58dd2e23d09b5153f3c3dad8a 100644 (file)
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -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)