2021-06-07 Bill Schmidt <wschm...@linux.ibm.com> gcc/ * config/rs6000/rs6000-gen-builtins.c (parse_args): New function. (parse_prototype): Implement. --- gcc/config/rs6000/rs6000-gen-builtins.c | 142 ++++++++++++++++++++++++ 1 file changed, 142 insertions(+)
diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c b/gcc/config/rs6000/rs6000-gen-builtins.c index 840b3f94295..7985d2d9a71 100644 --- a/gcc/config/rs6000/rs6000-gen-builtins.c +++ b/gcc/config/rs6000/rs6000-gen-builtins.c @@ -1059,6 +1059,91 @@ match_type (typeinfo *typedata, int voidok) return 1; } +/* Parse the argument list. */ +static parse_codes +parse_args (prototype *protoptr) +{ + typelist **argptr = &protoptr->args; + int *nargs = &protoptr->nargs; + int *restr_opnd = protoptr->restr_opnd; + restriction *restr = protoptr->restr; + char **val1 = protoptr->restr_val1; + char **val2 = protoptr->restr_val2; + int restr_cnt = 0; + + int success; + *nargs = 0; + + /* Start the argument list. */ + consume_whitespace (); + if (linebuf[pos] != '(') + { + (*diag) ("missing '(' at column %d.\n", pos + 1); + return PC_PARSEFAIL; + } + safe_inc_pos (); + + do { + consume_whitespace (); + int oldpos = pos; + typelist *argentry = (typelist *) malloc (sizeof (typelist)); + memset (argentry, 0, sizeof *argentry); + typeinfo *argtype = &argentry->info; + success = match_type (argtype, VOID_NOTOK); + if (success) + { + if (argtype->restr) + { + if (restr_cnt >= MAXRESTROPNDS) + { + (*diag) ("More than two %d operands\n", MAXRESTROPNDS); + return PC_PARSEFAIL; + } + restr_opnd[restr_cnt] = *nargs + 1; + restr[restr_cnt] = argtype->restr; + val1[restr_cnt] = argtype->val1; + val2[restr_cnt++] = argtype->val2; + } + (*nargs)++; + *argptr = argentry; + argptr = &argentry->next; + consume_whitespace (); + if (linebuf[pos] == ',') + safe_inc_pos (); + else if (linebuf[pos] != ')') + { + (*diag) ("arg not followed by ',' or ')' at column %d.\n", + pos + 1); + return PC_PARSEFAIL; + } + +#ifdef DEBUG + (*diag) ("argument type: isvoid = %d, isconst = %d, isvector = %d, \ +issigned = %d, isunsigned = %d, isbool = %d, ispixel = %d, ispointer = %d, \ +base = %d, restr = %d, val1 = \"%s\", val2 = \"%s\", pos = %d.\n", + argtype->isvoid, argtype->isconst, argtype->isvector, + argtype->issigned, argtype->isunsigned, argtype->isbool, + argtype->ispixel, argtype->ispointer, argtype->base, + argtype->restr, argtype->val1, argtype->val2, pos + 1); +#endif + } + else + { + free (argentry); + *argptr = NULL; + pos = oldpos; + if (linebuf[pos] != ')') + { + (*diag) ("badly terminated arg list at column %d.\n", pos + 1); + return PC_PARSEFAIL; + } + safe_inc_pos (); + } + } while (success); + + return PC_OK; +} + /* Parse the attribute list. */ static parse_codes parse_bif_attrs (attrinfo *attrptr) @@ -1071,6 +1156,63 @@ parse_bif_attrs (attrinfo *attrptr) static parse_codes parse_prototype (prototype *protoptr) { + typeinfo *ret_type = &protoptr->rettype; + char **bifname = &protoptr->bifname; + + /* Get the return type. */ + consume_whitespace (); + int oldpos = pos; + int success = match_type (ret_type, VOID_OK); + if (!success) + { + (*diag) ("missing or badly formed return type at column %d.\n", + oldpos + 1); + return PC_PARSEFAIL; + } + +#ifdef DEBUG + (*diag) ("return type: isvoid = %d, isconst = %d, isvector = %d, \ +issigned = %d, isunsigned = %d, isbool = %d, ispixel = %d, ispointer = %d, \ +base = %d, restr = %d, val1 = \"%s\", val2 = \"%s\", pos = %d.\n", + ret_type->isvoid, ret_type->isconst, ret_type->isvector, + ret_type->issigned, ret_type->isunsigned, ret_type->isbool, + ret_type->ispixel, ret_type->ispointer, ret_type->base, + ret_type->restr, ret_type->val1, ret_type->val2, pos + 1); +#endif + + /* Get the bif name. */ + consume_whitespace (); + oldpos = pos; + *bifname = match_identifier (); + if (!*bifname) + { + (*diag) ("missing function name at column %d.\n", oldpos + 1); + return PC_PARSEFAIL; + } + +#ifdef DEBUG + (*diag) ("function name is '%s'.\n", *bifname); +#endif + + /* Process arguments. */ + if (parse_args (protoptr) == PC_PARSEFAIL) + return PC_PARSEFAIL; + + /* Process terminating semicolon. */ + consume_whitespace (); + if (linebuf[pos] != ';') + { + (*diag) ("missing semicolon at column %d.\n", pos + 1); + return PC_PARSEFAIL; + } + safe_inc_pos (); + consume_whitespace (); + if (linebuf[pos] != '\n') + { + (*diag) ("garbage at end of line at column %d.\n", pos + 1); + return PC_PARSEFAIL; + } + return PC_OK; } -- 2.27.0