reverse the param order before building the function type and type check

varargs functions with specified params.
This commit is contained in:
Bill Currie 2002-05-08 17:33:28 +00:00
parent b03bfa7a6e
commit de86019d4b
6 changed files with 80 additions and 58 deletions

View file

@ -41,6 +41,8 @@ typedef struct param_s {
param_t *new_param (const char *selector, type_t *type, const char *name);
param_t *reverse_params (param_t *params);
type_t *parse_params (type_t *type, param_t *params);
void build_scope (function_t *f, def_t *func, param_t *params);
function_t *new_function (void);

View file

@ -1428,7 +1428,7 @@ function_expr (expr_t *e1, expr_t *e2)
{
etype_t t1;
expr_t *e;
int parm_count = 0;
int arg_count = 0, parm_count = 0;
type_t *ftype;
int i;
expr_t *args = 0, **a = &args;
@ -1443,7 +1443,7 @@ function_expr (expr_t *e1, expr_t *e2)
for (e = e2; e; e = e->next) {
if (e->type == ex_error)
return e;
parm_count++;
arg_count++;
}
t1 = extract_type (e1);
@ -1472,42 +1472,51 @@ function_expr (expr_t *e1, expr_t *e2)
ftype = e1->type == ex_def ? e1->e.def->type : e1->e.expr.type;
if (parm_count > MAX_PARMS) {
if (arg_count > MAX_PARMS) {
return error (e1, "more than %d parameters", MAX_PARMS);
}
if (ftype->num_parms != -1) {
if (parm_count > ftype->num_parms) {
return error (e1, "too many arguments");
} else if (parm_count < ftype->num_parms) {
if (ftype->num_parms < -1) {
if (arg_count > ftype->num_parms + 1) {
if (!options.traditional)
return error (e1, "too few arguments");
warning (e1, "too few arguments");
}
parm_count = -ftype->num_parms - 1;
} else if (ftype->num_parms >= 0) {
if (arg_count > ftype->num_parms) {
printf ("%d %d %s\n", arg_count, ftype->num_parms, e1->e.def->name);
return error (e1, "too many arguments");
} else if (arg_count < ftype->num_parms) {
if (!options.traditional)
return error (e1, "too few arguments");
warning (e1, "too few arguments");
}
parm_count = ftype->num_parms;
}
for (i = parm_count, e = e2; i > 0; i--, e = e->next) {
for (i = arg_count - 1, e = e2; i >= 0; i--, e = e->next) {
type_t *t = get_type (e);
if (ftype->parm_types[i - 1] == &type_float && e->type == ex_integer) {
if (ftype->parm_types[i] == &type_float && e->type == ex_integer) {
e->type = ex_float;
e->e.float_val = e->e.integer_val;
t = &type_float;
}
if (ftype->num_parms != -1) {
if (i < parm_count) {
if (t == &type_void) {
t = ftype->parm_types[i - 1];
t = ftype->parm_types[i];
e->type = expr_types[t->type];
}
if (t != ftype->parm_types[i - 1]) {
print_type (ftype->parm_types[i - 1]); puts("");
if (t != ftype->parm_types[i]) {
print_type (ftype->parm_types[i]); puts("");
print_type (t); puts("");
err = error (e, "type mismatch for parameter %d of %s",
i, e1->e.def->name);
i + 1, e1->e.def->name);
}
} else {
if (e->type == ex_integer && options.warnings.vararg_integer)
warning (e, "passing integer consant into ... function");
}
arg_types[parm_count - i] = t;
arg_types[arg_count - 1 - i] = t;
}
if (err)
return err;

View file

@ -48,10 +48,27 @@ new_param (const char *selector, type_t *type, const char *name)
return param;
}
static param_t *
_reverse_params (param_t *params, param_t *next)
{
param_t *p = params;
if (params->next)
p = _reverse_params (params->next, params);
params->next = next;
return p;
}
param_t *
reverse_params (param_t *params)
{
if (!params)
return 0;
return _reverse_params (params, 0);
}
type_t *
parse_params (type_t *type, param_t *parms)
{
int ellipsis = 0, i;
param_t *p;
type_t new;
@ -60,28 +77,21 @@ parse_params (type_t *type, param_t *parms)
new.aux_type = type;
new.num_parms = 0;
if (parms && !parms->selector && !parms->type && !parms->name) {
ellipsis = 1;
parms = parms->next;
}
if (ellipsis) {
new.num_parms = -1; // variable args
} else if (!parms) {
} else {
for (p = parms; p; p = p->next, new.num_parms++)
;
for (p = parms; p; p = p->next, new.num_parms++) {
if (new.num_parms > MAX_PARMS) {
error (0, "too many params");
return type;
}
i = 1;
do {
//puts (parms->name);
new.parm_types[new.num_parms - i] = parms->type;
i++;
parms = parms->next;
} while (parms);
if (!p->selector && !p->type && !p->name) {
if (p->next) {
error (0, "internal error");
abort ();
}
new.num_parms = -(new.num_parms + 1);
break;
} else {
new.parm_types[new.num_parms] = p->type;
}
}
//print_type (&new); puts("");
return PR_FindType (&new);
@ -90,29 +100,20 @@ parse_params (type_t *type, param_t *parms)
void
build_scope (function_t *f, def_t *func, param_t *params)
{
int i, count;
def_t *def;
param_t **param_list, *p;
for (p = params, count = 0; p; p = p->next, count++)
;
param_list = alloca (sizeof (param_t *) * i);
i = count;
for (p = params; p; p = p->next)
param_list[--i] = p;
int i;
def_t *def;
param_t *p;
func->alloc = &func->locals;
for (i = 0; i < count; i++) {
if (!param_list[i]->selector
&& !param_list[i]->type
&& !param_list[i]->name)
for (p = params, i = 0; p; p = p->next, i++) {
if (!p->selector && !p->type && !p->name)
continue; // ellipsis marker
def = PR_GetDef (param_list[i]->type, param_list[i]->name,
func, func->alloc);
def = PR_GetDef (p->type, p->name, func, func->alloc);
f->parm_ofs[i] = def->ofs;
if (i > 0 && f->parm_ofs[i] < f->parm_ofs[i - 1])
Error ("bad parm order");
//printf ("%s%s %d\n", p == params ? "" : " ", p->name, def->ofs);
def->used = 1; // don't warn for unused params
PR_DefInitialized (def); // params are assumed to be initialized
}
@ -142,7 +143,7 @@ void
finish_function (function_t *f)
{
dfunction_t *df;
int i;
int i, count;
// fill in the dfunction
df = &functions[numfunctions];
@ -159,7 +160,9 @@ finish_function (function_t *f)
df->numparms = f->def->type->num_parms;
df->locals = f->def->locals;
df->parm_start = 0;
for (i = 0; i < df->numparms; i++)
if ((count = df->numparms) < 0)
count = -count - 1;
for (i = 0; i < count; i++)
df->parm_size[i] = pr_type_size[f->def->type->parm_types[i]->type];
if (f->aux) {

View file

@ -103,7 +103,7 @@ PR_FindType (type_t *type)
{
def_t *def;
type_t *check;
int i;
int c, i;
for (check = pr.types; check; check = check->next) {
if (check->type != type->type
@ -117,11 +117,14 @@ PR_FindType (type_t *type)
if (check->num_parms == -1)
return check;
for (i = 0; i < type->num_parms; i++)
if ((c = check->num_parms) < 0)
c = -c - 1;
for (i = 0; i < c; i++)
if (check->parm_types[i] != type->parm_types[i])
break;
if (i == type->num_parms)
if (i == c)
return check;
}

View file

@ -237,7 +237,7 @@ function_decl
}
')'
{
$$ = $3;
$$ = reverse_params ($3);
}
| '(' param_scope param_list ',' ELLIPSIS ')'
{
@ -246,6 +246,7 @@ function_decl
$$ = new_param (0, 0, 0);
$$->next = $3;
$$ = reverse_params ($$);
}
| '(' ELLIPSIS ')'
{

View file

@ -110,13 +110,17 @@ print_type (type_t *type)
if (type->num_parms < 0) {
printf ("(...)");
} else {
int i;
int c, i;
printf ("(");
for (i = 0; i < type->num_parms; i++) {
if ((c = type->num_parms) < 0)
c = -c - 1;
for (i = 0; i < c; i++) {
if (i)
printf (", ");
print_type (type->parm_types[i]);
}
if (type->num_parms < 0)
printf (", ...");
printf (")");
}
break;