2 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3 * See the copyright notice in the ACK home directory, in the file "Copyright".
5 /* $Id: proto.c,v 1.25 1994/06/27 08:01:56 ceriel Exp $ */
6 /* P R O T O T Y P E F I D D L I N G */
12 #include "botch_free.h"
16 #include <flt_arith.h>
31 extern char options[];
34 register struct proto *pl;
36 register int errcnt = 0;
39 if ((pl->pl_flag & PL_VOID) && !(pl->next)) return;
42 if (pl->pl_flag & PL_VOID) {
43 if (!errcnt && !(pl->pl_flag & PL_ERRGIVEN))
44 error("illegal use of void in argument list");
45 pl->pl_flag |= PL_ERRGIVEN;
52 add_proto(pl, ds, dc, lvl)
55 struct declarator *dc;
58 /* The full typed identifier or abstract type, described
59 by the structures decspecs and declarator are turned
60 a into parameter type list structure.
61 The parameters will be declared at level L_FORMAL2,
62 later on it's decided whether they were prototypes
63 or actual declarations.
65 register struct idf *idf = dc->dc_idf;
66 register struct def *def = idf ? idf->id_def : (struct def *)0;
67 register int sc = ds->ds_sc;
68 register struct type *type;
69 char formal_array = 0;
71 ASSERT(ds->ds_type != (struct type *)0);
73 pl->pl_flag = PL_FORMAL;
74 type = declare_type(ds->ds_type, dc);
75 if (type->tp_size < (arith)0 && actual_declaration(sc, type)) {
76 extern char *symbol2str();
77 if (type->tp_fund != VOID)
78 error("unknown %s-type", symbol2str(type->tp_fund));
80 if (idf != (struct idf *)0
83 error("illegal use of void in argument list");
84 pl->pl_flag |= PL_ERRGIVEN;
86 /* set PL_VOID anyway */
87 pl->pl_flag |= PL_VOID;
90 if (ds->ds_sc_given && ds->ds_sc != REGISTER) {
91 if (!(pl->pl_flag & PL_ERRGIVEN)) {
92 if (ds->ds_sc != AUTO) {
93 error("illegal storage class in parameter declaration");
95 warning("illegal storage class in parameter declaration");
100 /* Perform some special conversions for parameters.
102 if (type->tp_fund == FUNCTION) {
103 type = construct_type(POINTER, type, 0, (arith) 0, NO_PROTO);
104 } else if (type->tp_fund == ARRAY) {
105 type = construct_type(POINTER, type->tp_up, 0, (arith) 0, NO_PROTO);
109 /* According to the standard we should ignore the storage
110 class of a parameter, unless it's part of a function
112 However, in the routine declare_protos we don't know decspecs,
113 and therefore we can't complain up there. So we build up the
114 storage class, and keep quiet until we reach declare_protos.
116 sc = (ds->ds_sc_given && ds->ds_sc != REGISTER) ?
117 0 : sc == 0 ? FORMAL : REGISTER;
119 if (def && (def->df_level == lvl /* || def->df_level < L_PROTO */ )) {
120 /* redeclaration at the same level */
121 error("parameter %s redeclared", idf->id_text);
122 } else if (idf != (struct idf *)0) {
123 /* New definition, redefinition hides earlier one
125 register struct def *newdef = new_def();
128 newdef->df_level = lvl;
130 newdef->df_type = type;
131 newdef->df_formal_array = formal_array;
132 newdef->df_file = idf->id_file;
133 newdef->df_line = idf->id_line;
135 newdef->df_set = (type->tp_fund == ARRAY);
136 /* newdef->df_firstbrace = 0; */
138 /* We can't put the idf onto the stack, since these kinds
139 of declaration may occurs at any level, and the idf
140 does not necessarily go at this level. E.g.
144 { int func(int a, int b);
149 The idf's a and b declared in the prototype declaration
150 do not go at any level, they are simply ignored.
157 They should go at level L_FORMAL2. But at this stage
158 we don't know whether we have a prototype or function
159 definition. So, this process is postponed.
161 idf->id_def = newdef;
174 struct tag *tg = (struct tag *)0;
175 register int fund = tp->tp_fund;
177 while (fund == FIELD || fund == POINTER
178 || fund == ARRAY || fund == FUNCTION) {
183 switch(tp->tp_fund) {
186 case STRUCT: tg = tp->tp_idf->id_tag; break;
193 register struct declarator *dc;
195 /* At this points we know that the idf's in protolist are formal
196 parameters. So it's time to declare them at level L_FORMAL2.
198 struct stack_level *stl = stack_level_of(L_FORMAL1);
199 register struct decl_unary *du;
200 register struct type *type;
201 register struct proto *pl;
202 register struct def *def;
206 dumpidftab("start declare_protos", 0);
208 du = dc->dc_decl_unary;
210 if (du->du_fund == FUNCTION) {
211 if (du->next != (struct decl_unary *) 0) {
212 remove_proto_idfs(du->du_proto);
218 pl = du ? du->du_proto : NO_PROTO;
220 #if 0 /* the id_proto member is deleted (???) */
229 /* `...' only for type checking */
230 if (pl->pl_flag & PL_ELLIPSIS) {
235 /* special case: int f(void) { ; } */
236 if (type->tp_fund == VOID)
239 if (!pl->pl_idf || !(def = pl->pl_idf->id_def)) {
240 error("no parameter identifier supplied");
245 /* Postponed storage class checking.
248 error("illegal storage class in parameter declaration");
250 def->df_level = L_FORMAL2;
251 stack_idf(pl->pl_idf, stl);
254 tg = gettag(type, &idp);
255 if (tg && tg->tg_level <= L_PROTO) {
256 tg->tg_level = L_FORMAL2;
263 dumpidftab("end declare_protos", 0);
268 update_proto(tp, otp)
269 register struct type *tp, *otp;
271 /* This routine performs the proto type updates.
272 Consider the following code:
275 int f(double g(int f(), int));
276 int f(double g(int f(long double), int));
278 The most accurate definition is the third line.
279 This routine will silently update all lists,
280 and removes the redundant occupied space.
282 register struct proto *pl, *opl;
284 if (tp == otp) return;
285 if (!tp || !otp) return;
287 while (tp->tp_fund != FUNCTION) {
288 if (tp->tp_fund != POINTER && tp->tp_fund != ARRAY) return;
297 /* both have prototypes */
299 update_proto(pl->pl_type, opl->pl_type);
303 /* Do not free the old prototype list. It might be part of
306 otp->tp_proto = tp->tp_proto;
308 /* old decl has type */
313 update_proto(tp->tp_up, otp->tp_up);
316 /* struct/union and enum tags can be declared inside prototypes
317 * remove them from the symbol-table
322 register struct idf *ident;
323 register struct tag *tgp, **tgpp;
324 register int fund = tp->tp_fund;
326 while (fund == FIELD || fund == POINTER
327 || fund == ARRAY || fund == FUNCTION) {
333 switch (tp->tp_fund) {
336 case UNION: tgpp = &(ident->id_tag); break;
340 while((*tgpp) && (*tgpp)->tg_type != tp) {
341 tgpp = &((*tgpp)->next);
346 if (tgp->tg_level > L_PROTO) return;
350 print("Removing idf %s from list\n",
358 remove_proto_idfs(pl)
359 register struct proto *pl;
361 /* Remove all the identifier definitions from the
364 register struct def *def;
370 print("Removing idf %s from list\n",
371 pl->pl_idf->id_text);
373 def = pl->pl_idf->id_def;
374 if (def && def->df_level <= L_PROTO) {
375 pl->pl_idf->id_def = def->next;
378 pl->pl_idf = (struct idf *) 0;
381 remove_proto_tag(pl->pl_type);
388 register struct expr **expp;
390 /* If the function specified by (*expp)->OP_LEFT has a prototype,
391 the parameters are converted according the rules specified in
392 par. 3.3.2.2. E.i. the parameters are converted to the prototype
393 counter parts as if by assignment. For the parameters falling
394 under ellipsis clause the old parameters conversion stuff
397 register struct expr *left = (*expp)->OP_LEFT;
398 register struct expr *right = (*expp)->OP_RIGHT;
399 register struct proto *pl = NO_PROTO;
400 static struct proto ellipsis = { 0, 0, 0, PL_ELLIPSIS };
402 if (left != NILEXPR) { /* in case of an error */
403 register struct type *tp = left->ex_type;
405 while (tp && tp->tp_fund != FUNCTION && tp != error_type)
407 if (tp && tp->tp_proto)
411 if (right != NILEXPR) { /* function call with parameters */
412 register struct expr **ep = &((*expp)->OP_RIGHT);
413 register int ecnt = 0, pcnt = 0;
414 struct expr **estack[NPARAMS];
415 struct proto *pstack[NPARAMS];
417 /* stack up the parameter expressions */
418 while (right->ex_class == Oper && right->OP_OPER == PARCOMMA) {
419 if (ecnt == STDC_NPARAMS)
420 expr_strict(right, "number of parameters exceeds ANSI limit");
421 if (ecnt >= NPARAMS-1) {
422 expr_error(right, "too many parameters");
425 estack[ecnt++] = &(right->OP_RIGHT);
426 ep = &(right->OP_LEFT);
427 right = right->OP_LEFT;
431 /* Declarations like int f(void) do not expect any
434 if (pl && pl->pl_flag & PL_VOID) {
435 expr_strict(*expp, "no parameters expected");
439 /* stack up the prototypes */
443 /* stack prototypes */
449 pstack[0] = &ellipsis;
452 for (ecnt; ecnt >= 0; ecnt--) {
453 /* Only the parameters specified in the prototype
454 are checked and converted. The parameters that
455 fall under the ellipsis clause are neither
456 checked nor converted !
459 expr_error(*expp, "more parameters than specified in prototype");
462 else if (!(pstack[pcnt]->pl_flag & PL_ELLIPSIS)) {
463 ch3cast(estack[ecnt],CASTAB,pstack[pcnt]->pl_type);
466 any2parameter(estack[ecnt]);
468 if (pcnt > 0 || (pcnt == 0 && !(pstack[0]->pl_flag & PL_ELLIPSIS)))
469 expr_error(*expp, "fewer parameters than specified in prototype");
471 if (pl && !(pl->pl_flag & PL_VOID))
472 expr_error(*expp, "fewer parameters than specified in prototype");