mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-17 01:11:45 +00:00
reverse the param order before building the function type and type check
varargs functions with specified params.
This commit is contained in:
parent
b03bfa7a6e
commit
de86019d4b
6 changed files with 80 additions and 58 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 ')'
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue