diff options
Diffstat (limited to 'gcc/gcc.c')
-rw-r--r-- | gcc/gcc.c | 102 |
1 files changed, 56 insertions, 46 deletions
diff --git a/gcc/gcc.c b/gcc/gcc.c index 7a5056a5ba0..878f0441229 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -516,15 +516,18 @@ or with constant text in a single argument. part of that switch that matched the '*'. %{.S:X} substitutes X, if processing a file with suffix S. %{!.S:X} substitutes X, if NOT processing a file with suffix S. - + %{,S:X} substitutes X, if processing a file which will use spec S. + %{!,S:X} substitutes X, if NOT processing a file which will use spec S. + %{S|T:X} substitutes X if either -S or -T was given to CC. This may be - combined with !, ., and * as above binding stronger than the OR. + combined with '!', '.', ',', and '*' as above binding stronger + than the OR. If %* appears in X, all of the alternatives must be starred, and only the first matching alternative is substituted. %{S:X; if S was given to CC, substitutes X; T:Y; else if T was given to CC, substitutes Y; :D} else substitutes D. There can be as many clauses as you need. - This may be combined with ., !, |, and * as above. + This may be combined with '.', '!', ',', '|', and '*' as above. %(Spec) processes a specification defined in a specs file as *Spec: %[Spec] as above, but put __ around -D arguments @@ -5529,27 +5532,24 @@ handle_spec_function (const char *p) static inline bool input_suffix_matches (const char *atom, const char *end_atom) { - /* We special case the semantics of {.s:...} and {.S:...} and their - negative variants. Instead of testing the input filename suffix, - we test whether the input source file is an assembler file or an - assembler-with-cpp file respectively. This allows us to correctly - handle the -x command line option. */ - - if (atom + 1 == end_atom - && input_file_compiler - && input_file_compiler->suffix) - { - if (*atom == 's') - return !strcmp (input_file_compiler->suffix, "@assembler"); - if (*atom == 'S') - return !strcmp (input_file_compiler->suffix, "@assembler-with-cpp"); - } - return (input_suffix && !strncmp (input_suffix, atom, end_atom - atom) && input_suffix[end_atom - atom] == '\0'); } +/* Subroutine of handle_braces. Returns true if the current + input file's spec name matches the atom bracketed by ATOM and END_ATOM. */ +static bool +input_spec_matches (const char *atom, const char *end_atom) +{ + return (input_file_compiler + && input_file_compiler->suffix + && input_file_compiler->suffix[0] != '\0' + && !strncmp (input_file_compiler->suffix + 1, atom, + end_atom - atom) + && input_file_compiler->suffix[end_atom - atom + 1] == '\0'); +} + /* Subroutine of handle_braces. Returns true if a switch matching the atom bracketed by ATOM and END_ATOM appeared on the command line. */ @@ -5613,6 +5613,7 @@ handle_braces (const char *p) const char *orig = p; bool a_is_suffix; + bool a_is_spectype; bool a_is_starred; bool a_is_negated; bool a_matched; @@ -5633,8 +5634,12 @@ handle_braces (const char *p) goto invalid; /* Scan one "atom" (S in the description above of %{}, possibly - with !, ., or * modifiers). */ - a_matched = a_is_suffix = a_is_starred = a_is_negated = false; + with '!', '.', '@', ',', or '*' modifiers). */ + a_matched = false; + a_is_suffix = false; + a_is_starred = false; + a_is_negated = false; + a_is_spectype = false; SKIP_WHITE(); if (*p == '!') @@ -5643,6 +5648,8 @@ handle_braces (const char *p) SKIP_WHITE(); if (*p == '.') p++, a_is_suffix = true; + else if (*p == ',') + p++, a_is_spectype = true; atom = p; while (ISIDNUM(*p) || *p == '-' || *p == '+' || *p == '=' @@ -5660,7 +5667,7 @@ handle_braces (const char *p) /* Substitute the switch(es) indicated by the current atom. */ ordered_set = true; if (disjunct_set || n_way_choice || a_is_negated || a_is_suffix - || atom == end_atom) + || a_is_spectype || atom == end_atom) goto invalid; mark_matching_switches (atom, end_atom, a_is_starred); @@ -5679,7 +5686,8 @@ handle_braces (const char *p) if (atom == end_atom) { if (!n_way_choice || disj_matched || *p == '|' - || a_is_negated || a_is_suffix || a_is_starred) + || a_is_negated || a_is_suffix || a_is_spectype + || a_is_starred) goto invalid; /* An empty term may appear as the last choice of an @@ -5690,28 +5698,30 @@ handle_braces (const char *p) } else { - if (a_is_suffix && a_is_starred) - goto invalid; - - if (!a_is_starred) - disj_starred = false; - - /* Don't bother testing this atom if we already have a - match. */ - if (!disj_matched && !n_way_matched) - { - if (a_is_suffix) - a_matched = input_suffix_matches (atom, end_atom); - else - a_matched = switch_matches (atom, end_atom, a_is_starred); - - if (a_matched != a_is_negated) - { - disj_matched = true; - d_atom = atom; - d_end_atom = end_atom; - } - } + if ((a_is_suffix || a_is_spectype) && a_is_starred) + goto invalid; + + if (!a_is_starred) + disj_starred = false; + + /* Don't bother testing this atom if we already have a + match. */ + if (!disj_matched && !n_way_matched) + { + if (a_is_suffix) + a_matched = input_suffix_matches (atom, end_atom); + else if (a_is_spectype) + a_matched = input_spec_matches (atom, end_atom); + else + a_matched = switch_matches (atom, end_atom, a_is_starred); + + if (a_matched != a_is_negated) + { + disj_matched = true; + d_atom = atom; + d_end_atom = end_atom; + } + } } if (*p == ':') @@ -6940,7 +6950,7 @@ next_member: p++; SKIP_WHITE (); - if (*p == '.') + if (*p == '.' || *p == ',') suffix = true, p++; atom = p; |