diff options
Diffstat (limited to 'gcc/genpreds.c')
-rw-r--r-- | gcc/genpreds.c | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/gcc/genpreds.c b/gcc/genpreds.c index bf53944e297..7534a7c875e 100644 --- a/gcc/genpreds.c +++ b/gcc/genpreds.c @@ -674,6 +674,7 @@ struct constraint_data unsigned int is_extra : 1; unsigned int is_memory : 1; unsigned int is_address : 1; + unsigned int is_overloaded : 1; /* Set for all but the first definition. */ }; /* Overview of all constraints beginning with a given letter. */ @@ -757,6 +758,7 @@ add_constraint (const char *name, const char *regclass, bool is_const_int; bool is_const_dbl; size_t namelen; + bool is_overloaded = 0; if (exp && validate_exp (exp, name, lineno)) return; @@ -816,10 +818,29 @@ add_constraint (const char *name, const char *regclass, if (!strcmp ((*iter)->name, name)) { - message_with_line (lineno, "redefinition of constraint '%s'", name); - message_with_line ((*iter)->lineno, "previous definition is here"); - have_error = 1; - return; + /* An exact match is OK if the purpose is to overload the constraint. + */ + if (is_overloaded) + ; /* We've already warned against the 1st definition. */ + else if ((*iter)->is_register != (regclass != 0) + || (*iter)->is_memory != is_memory + || (*iter)->is_address != is_address) + { + message_with_line (lineno, + "overloading of constraint '%s'", name); + message_with_line ((*iter)->lineno, + "previous definition is here"); + is_overloaded = 1; + } + else + { + message_with_line (lineno, + "redefinition of constraint '%s'", name); + message_with_line ((*iter)->lineno, + "previous definition is here"); + have_error = 1; + return; + } } else if (!strncmp ((*iter)->name, name, (*iter)->namelen)) { @@ -910,6 +931,7 @@ add_constraint (const char *name, const char *regclass, c->is_extra = !(regclass || is_const_int || is_const_dbl); c->is_memory = is_memory; c->is_address = is_address; + c->is_overloaded = is_overloaded; c->next_this_letter = *slot; *slot = c; @@ -958,7 +980,8 @@ write_enum_constraint_num (void) "{\n" " CONSTRAINT__UNKNOWN = 0", stdout); FOR_ALL_CONSTRAINTS (c) - printf (",\n CONSTRAINT_%s", c->c_name); + if (!c->is_overloaded) + printf (",\n CONSTRAINT_%s", c->c_name); puts ("\n};\n"); } @@ -987,9 +1010,10 @@ write_lookup_constraint (void) { do { - printf (" if (!strncmp (str, \"%s\", %lu))\n" - " return CONSTRAINT_%s;\n", - c->name, (unsigned long int) c->namelen, c->c_name); + if (!c->is_overloaded) + printf (" if (!strncmp (str, \"%s\", %lu))\n" + " return CONSTRAINT_%s;\n", + c->name, (unsigned long int) c->namelen, c->c_name); c = c->next_this_letter; } while (c); |