* added compilers lcc and bcc (linux86)
[mascara-docs.git] / compilers / lcc-4.2 / src / decl.c
blob204f46ebe94348ba58b68706d102452a7828030e
1 #include "c.h"
3 static char rcsid[] = "$Id$";
5 #define add(x,n) (x > inttype->u.sym->u.limits.max.i-(n) ? (overflow=1,x) : x+(n))
6 #define chkoverflow(x,n) ((void)add(x,n))
7 #define bits2bytes(n) (((n) + 7)/8)
8 static int regcount;
10 static List autos, registers;
11 Symbol cfunc; /* current function */
12 Symbol retv; /* return value location for structs */
14 static void checkref(Symbol, void *);
15 static Symbol dclglobal(int, char *, Type, Coordinate *);
16 static Symbol dcllocal(int, char *, Type, Coordinate *);
17 static Symbol dclparam(int, char *, Type, Coordinate *);
18 static Type dclr(Type, char **, Symbol **, int);
19 static Type dclr1(char **, Symbol **, int);
20 static void decl(Symbol (*)(int, char *, Type, Coordinate *));
21 extern void doconst(Symbol, void *);
22 static void doglobal(Symbol, void *);
23 static void doextern(Symbol, void *);
24 static void exitparams(Symbol []);
25 static void fields(Type);
26 static void funcdefn(int, char *, Type, Symbol [], Coordinate);
27 static void initglobal(Symbol, int);
28 static void oldparam(Symbol, void *);
29 static Symbol *parameters(Type);
30 static Type specifier(int *);
31 static Type structdcl(int);
32 static Type tnode(int, Type);
33 void program(void) {
34 int n;
36 level = GLOBAL;
37 for (n = 0; t != EOI; n++)
38 if (kind[t] == CHAR || kind[t] == STATIC
39 || t == ID || t == '*' || t == '(') {
40 decl(dclglobal);
41 deallocate(STMT);
42 if (!(glevel >= 3 || xref))
43 deallocate(FUNC);
44 } else if (t == ';') {
45 warning("empty declaration\n");
46 t = gettok();
47 } else {
48 error("unrecognized declaration\n");
49 t = gettok();
51 if (n == 0)
52 warning("empty input file\n");
54 static Type specifier(int *sclass) {
55 int cls, cons, sign, size, type, vol;
56 Type ty = NULL;
58 cls = vol = cons = sign = size = type = 0;
59 if (sclass == NULL)
60 cls = AUTO;
61 for (;;) {
62 int *p, tt = t;
63 switch (t) {
64 case AUTO:
65 case REGISTER: if (level <= GLOBAL && cls == 0)
66 error("invalid use of `%k'\n", t);
67 p = &cls; t = gettok(); break;
68 case STATIC: case EXTERN:
69 case TYPEDEF: p = &cls; t = gettok(); break;
70 case CONST: p = &cons; t = gettok(); break;
71 case VOLATILE: p = &vol; t = gettok(); break;
72 case SIGNED:
73 case UNSIGNED: p = &sign; t = gettok(); break;
74 case LONG: if (size == LONG) {
75 size = 0;
76 tt = LONG+LONG;
78 p = &size; t = gettok(); break;
79 case SHORT: p = &size; t = gettok(); break;
80 case VOID: case CHAR: case INT: case FLOAT:
81 case DOUBLE: p = &type; ty = tsym->type;
82 t = gettok(); break;
83 case ENUM: p = &type; ty = enumdcl(); break;
84 case STRUCT:
85 case UNION: p = &type; ty = structdcl(t); break;
86 case ID:
87 if (istypename(t, tsym) && type == 0
88 && sign == 0 && size == 0) {
89 use(tsym, src);
90 ty = tsym->type;
91 if (isqual(ty)
92 && ty->size != ty->type->size) {
93 ty = unqual(ty);
94 if (isconst(tsym->type))
95 ty = qual(CONST, ty);
96 if (isvolatile(tsym->type))
97 ty = qual(VOLATILE, ty);
98 tsym->type = ty;
100 p = &type;
101 t = gettok();
102 } else
103 p = NULL;
104 break;
105 default: p = NULL;
107 if (p == NULL)
108 break;
109 if (*p)
110 error("invalid use of `%k'\n", tt);
111 *p = tt;
113 if (sclass)
114 *sclass = cls;
115 if (type == 0) {
116 type = INT;
117 ty = inttype;
119 if (size == SHORT && type != INT
120 || size == LONG+LONG && type != INT
121 || size == LONG && type != INT && type != DOUBLE
122 || sign && type != INT && type != CHAR)
123 error("invalid type specification\n");
124 if (type == CHAR && sign)
125 ty = sign == UNSIGNED ? unsignedchar : signedchar;
126 else if (size == SHORT)
127 ty = sign == UNSIGNED ? unsignedshort : shorttype;
128 else if (size == LONG && type == DOUBLE)
129 ty = longdouble;
130 else if (size == LONG+LONG) {
131 ty = sign == UNSIGNED ? unsignedlonglong : longlong;
132 if (Aflag >= 1)
133 warning("`%t' is a non-ANSI type\n", ty);
134 } else if (size == LONG)
135 ty = sign == UNSIGNED ? unsignedlong : longtype;
136 else if (sign == UNSIGNED && type == INT)
137 ty = unsignedtype;
138 if (cons == CONST)
139 ty = qual(CONST, ty);
140 if (vol == VOLATILE)
141 ty = qual(VOLATILE, ty);
142 return ty;
144 static void decl(Symbol (*dcl)(int, char *, Type, Coordinate *)) {
145 int sclass;
146 Type ty, ty1;
147 static char stop[] = { CHAR, STATIC, ID, 0 };
149 ty = specifier(&sclass);
150 if (t == ID || t == '*' || t == '(' || t == '[') {
151 char *id;
152 Coordinate pos;
153 id = NULL;
154 pos = src;
155 if (level == GLOBAL) {
156 Symbol *params = NULL;
157 ty1 = dclr(ty, &id, &params, 0);
158 if (params && id && isfunc(ty1)
159 && (t == '{' || istypename(t, tsym)
160 || (kind[t] == STATIC && t != TYPEDEF))) {
161 if (sclass == TYPEDEF) {
162 error("invalid use of `typedef'\n");
163 sclass = EXTERN;
165 if (ty1->u.f.oldstyle)
166 exitscope();
167 funcdefn(sclass, id, ty1, params, pos);
168 return;
169 } else if (params)
170 exitparams(params);
171 } else
172 ty1 = dclr(ty, &id, NULL, 0);
173 for (;;) {
174 if (Aflag >= 1 && !hasproto(ty1))
175 warning("missing prototype\n");
176 if (id == NULL)
177 error("missing identifier\n");
178 else if (sclass == TYPEDEF)
180 Symbol p = lookup(id, identifiers);
181 if (p && p->scope == level)
182 error("redeclaration of `%s'\n", id);
183 p = install(id, &identifiers, level,
184 level < LOCAL ? PERM : FUNC);
185 p->type = ty1;
186 p->sclass = TYPEDEF;
187 p->src = pos;
189 else
190 (void)(*dcl)(sclass, id, ty1, &pos);
191 if (t != ',')
192 break;
193 t = gettok();
194 id = NULL;
195 pos = src;
196 ty1 = dclr(ty, &id, NULL, 0);
198 } else if (ty == NULL
199 || !(isenum(ty) ||
200 isstruct(ty) && (*unqual(ty)->u.sym->name < '1' || *unqual(ty)->u.sym->name > '9')))
201 error("empty declaration\n");
202 test(';', stop);
204 static Symbol dclglobal(int sclass, char *id, Type ty, Coordinate *pos) {
205 Symbol p;
207 if (sclass == 0)
208 sclass = AUTO;
209 else if (sclass != EXTERN && sclass != STATIC) {
210 error("invalid storage class `%k' for `%t %s'\n",
211 sclass, ty, id);
212 sclass = AUTO;
214 p = lookup(id, identifiers);
215 if (p && p->scope == GLOBAL) {
216 if (p->sclass != TYPEDEF && eqtype(ty, p->type, 1))
217 ty = compose(ty, p->type);
218 else
219 error("redeclaration of `%s' previously declared at %w\n", p->name, &p->src);
221 if (!isfunc(ty) && p->defined && t == '=')
222 error("redefinition of `%s' previously defined at %w\n", p->name, &p->src);
224 if (p->sclass == EXTERN && sclass == STATIC
225 || p->sclass == STATIC && sclass == AUTO
226 || p->sclass == AUTO && sclass == STATIC)
227 warning("inconsistent linkage for `%s' previously declared at %w\n", p->name, &p->src);
230 if (p == NULL || p->scope != GLOBAL) {
231 Symbol q = lookup(id, externals);
232 if (q) {
233 if (sclass == STATIC || !eqtype(ty, q->type, 1))
234 warning("declaration of `%s' does not match previous declaration at %w\n", id, &q->src);
236 p = relocate(id, externals, globals);
237 p->sclass = sclass;
238 } else {
239 p = install(id, &globals, GLOBAL, PERM);
240 p->sclass = sclass;
241 (*IR->defsymbol)(p);
243 if (p->sclass != STATIC) {
244 static int nglobals;
245 nglobals++;
246 if (Aflag >= 2 && nglobals == 512)
247 warning("more than 511 external identifiers\n");
249 } else if (p->sclass == EXTERN)
250 p->sclass = sclass;
251 p->type = ty;
252 p->src = *pos;
253 if (t == '=' && isfunc(p->type)) {
254 error("illegal initialization for `%s'\n", p->name);
255 t = gettok();
256 initializer(p->type, 0);
257 } else if (t == '=') {
258 initglobal(p, 0);
259 if (glevel > 0 && IR->stabsym) {
260 (*IR->stabsym)(p); swtoseg(p->u.seg); }
261 } else if (p->sclass == STATIC && !isfunc(p->type)
262 && p->type->size == 0)
263 error("undefined size for `%t %s'\n", p->type, p->name);
264 return p;
266 static void initglobal(Symbol p, int flag) {
267 Type ty;
269 if (t == '=' || flag) {
270 if (p->sclass == STATIC) {
271 for (ty = p->type; isarray(ty); ty = ty->type)
273 defglobal(p, isconst(ty) ? LIT : DATA);
274 } else
275 defglobal(p, DATA);
276 if (t == '=')
277 t = gettok();
278 ty = initializer(p->type, 0);
279 if (isarray(p->type) && p->type->size == 0)
280 p->type = ty;
281 if (p->sclass == EXTERN)
282 p->sclass = AUTO;
285 void defglobal(Symbol p, int seg) {
286 p->u.seg = seg;
287 swtoseg(p->u.seg);
288 if (p->sclass != STATIC)
289 (*IR->export)(p);
290 (*IR->global)(p);
291 p->defined = 1;
294 static Type dclr(Type basety, char **id, Symbol **params, int abstract) {
295 Type ty = dclr1(id, params, abstract);
297 for ( ; ty; ty = ty->type)
298 switch (ty->op) {
299 case POINTER:
300 basety = ptr(basety);
301 break;
302 case FUNCTION:
303 basety = func(basety, ty->u.f.proto,
304 ty->u.f.oldstyle);
305 break;
306 case ARRAY:
307 basety = array(basety, ty->size, 0);
308 break;
309 case CONST: case VOLATILE:
310 basety = qual(ty->op, basety);
311 break;
312 default: assert(0);
314 if (Aflag >= 2 && basety->size > 32767)
315 warning("more than 32767 bytes in `%t'\n", basety);
316 return basety;
318 static Type tnode(int op, Type type) {
319 Type ty;
321 NEW0(ty, STMT);
322 ty->op = op;
323 ty->type = type;
324 return ty;
326 static Type dclr1(char **id, Symbol **params, int abstract) {
327 Type ty = NULL;
329 switch (t) {
330 case ID: if (id)
331 *id = token;
332 else
333 error("extraneous identifier `%s'\n", token);
334 t = gettok(); break;
335 case '*': t = gettok(); if (t == CONST || t == VOLATILE) {
336 Type ty1;
337 ty1 = ty = tnode(t, NULL);
338 while ((t = gettok()) == CONST || t == VOLATILE)
339 ty1 = tnode(t, ty1);
340 ty->type = dclr1(id, params, abstract);
341 ty = ty1;
342 } else
343 ty = dclr1(id, params, abstract);
344 ty = tnode(POINTER, ty); break;
345 case '(': t = gettok(); if (abstract
346 && (t == REGISTER || istypename(t, tsym) || t == ')')) {
347 Symbol *args;
348 ty = tnode(FUNCTION, ty);
349 enterscope();
350 if (level > PARAM)
351 enterscope();
352 args = parameters(ty);
353 exitparams(args);
354 } else {
355 ty = dclr1(id, params, abstract);
356 expect(')');
357 if (abstract && ty == NULL
358 && (id == NULL || *id == NULL))
359 return tnode(FUNCTION, NULL);
360 } break;
361 case '[': break;
362 default: return ty;
364 while (t == '(' || t == '[')
365 switch (t) {
366 case '(': t = gettok(); { Symbol *args;
367 ty = tnode(FUNCTION, ty);
368 enterscope();
369 if (level > PARAM)
370 enterscope();
371 args = parameters(ty);
372 if (params && *params == NULL)
373 *params = args;
374 else
375 exitparams(args);
377 break;
378 case '[': t = gettok(); { int n = 0;
379 if (kind[t] == ID) {
380 n = intexpr(']', 1);
381 if (n <= 0) {
382 error("`%d' is an illegal array size\n", n);
383 n = 1;
385 } else
386 expect(']');
387 ty = tnode(ARRAY, ty);
388 ty->size = n; } break;
389 default: assert(0);
391 return ty;
393 static Symbol *parameters(Type fty) {
394 List list = NULL;
395 Symbol *params;
397 if (kind[t] == STATIC || istypename(t, tsym)) {
398 int n = 0;
399 Type ty1 = NULL;
400 for (;;) {
401 Type ty;
402 int sclass = 0;
403 char *id = NULL;
404 if (ty1 && t == ELLIPSIS) {
405 static struct symbol sentinel;
406 if (sentinel.type == NULL) {
407 sentinel.type = voidtype;
408 sentinel.defined = 1;
410 if (ty1 == voidtype)
411 error("illegal formal parameter types\n");
412 list = append(&sentinel, list);
413 t = gettok();
414 break;
416 if (!istypename(t, tsym) && t != REGISTER)
417 error("missing parameter type\n");
418 n++;
419 ty = dclr(specifier(&sclass), &id, NULL, 1);
420 if ( ty == voidtype && (ty1 || id)
421 || ty1 == voidtype)
422 error("illegal formal parameter types\n");
423 if (id == NULL)
424 id = stringd(n);
425 if (ty != voidtype)
426 list = append(dclparam(sclass, id, ty, &src), list);
427 if (Aflag >= 1 && !hasproto(ty))
428 warning("missing prototype\n");
429 if (ty1 == NULL)
430 ty1 = ty;
431 if (t != ',')
432 break;
433 t = gettok();
435 fty->u.f.proto = newarray(length(list) + 1,
436 sizeof (Type *), PERM);
437 params = ltov(&list, FUNC);
438 for (n = 0; params[n]; n++)
439 fty->u.f.proto[n] = params[n]->type;
440 fty->u.f.proto[n] = NULL;
441 fty->u.f.oldstyle = 0;
442 } else {
443 if (t == ID)
444 for (;;) {
445 Symbol p;
446 if (t != ID) {
447 error("expecting an identifier\n");
448 break;
450 p = dclparam(0, token, inttype, &src);
451 p->defined = 0;
452 list = append(p, list);
453 t = gettok();
454 if (t != ',')
455 break;
456 t = gettok();
458 params = ltov(&list, FUNC);
459 fty->u.f.proto = NULL;
460 fty->u.f.oldstyle = 1;
462 if (t != ')') {
463 static char stop[] = { CHAR, STATIC, IF, ')', 0 };
464 expect(')');
465 skipto('{', stop);
467 if (t == ')')
468 t = gettok();
469 return params;
471 static void exitparams(Symbol params[]) {
472 assert(params);
473 if (params[0] && !params[0]->defined)
474 error("extraneous old-style parameter list\n");
475 if (level > PARAM)
476 exitscope();
477 exitscope();
480 static Symbol dclparam(int sclass, char *id, Type ty, Coordinate *pos) {
481 Symbol p;
483 if (isfunc(ty))
484 ty = ptr(ty);
485 else if (isarray(ty))
486 ty = atop(ty);
487 if (sclass == 0)
488 sclass = AUTO;
489 else if (sclass != REGISTER) {
490 error("invalid storage class `%k' for `%t%s\n",
491 sclass, ty, stringf(id ? " %s'" : "' parameter", id));
492 sclass = AUTO;
493 } else if (isvolatile(ty) || isstruct(ty)) {
494 warning("register declaration ignored for `%t%s\n",
495 ty, stringf(id ? " %s'" : "' parameter", id));
496 sclass = AUTO;
499 p = lookup(id, identifiers);
500 if (p && p->scope == level)
501 error("duplicate declaration for `%s' previously declared at %w\n", id, &p->src);
503 else
504 p = install(id, &identifiers, level, FUNC);
505 p->sclass = sclass;
506 p->src = *pos;
507 p->type = ty;
508 p->defined = 1;
509 if (t == '=') {
510 error("illegal initialization for parameter `%s'\n", id);
511 t = gettok();
512 (void)expr1(0);
514 return p;
516 static Type structdcl(int op) {
517 char *tag;
518 Type ty;
519 Symbol p;
520 Coordinate pos;
522 t = gettok();
523 pos = src;
524 if (t == ID) {
525 tag = token;
526 t = gettok();
527 } else
528 tag = "";
529 if (t == '{') {
530 static char stop[] = { IF, ',', 0 };
531 ty = newstruct(op, tag);
532 ty->u.sym->src = pos;
533 ty->u.sym->defined = 1;
534 t = gettok();
535 if (istypename(t, tsym))
536 fields(ty);
537 else
538 error("invalid %k field declarations\n", op);
539 test('}', stop);
541 else if (*tag && (p = lookup(tag, types)) != NULL
542 && p->type->op == op) {
543 ty = p->type;
544 if (t == ';' && p->scope < level)
545 ty = newstruct(op, tag);
547 else {
548 if (*tag == 0)
549 error("missing %k tag\n", op);
550 ty = newstruct(op, tag);
552 if (*tag && xref)
553 use(ty->u.sym, pos);
554 return ty;
556 static void fields(Type ty) {
557 { int n = 0;
558 while (istypename(t, tsym)) {
559 static char stop[] = { IF, CHAR, '}', 0 };
560 Type ty1 = specifier(NULL);
561 for (;;) {
562 Field p;
563 char *id = NULL;
564 Type fty = dclr(ty1, &id, NULL, 0);
565 p = newfield(id, ty, fty);
566 if (Aflag >= 1 && !hasproto(p->type))
567 warning("missing prototype\n");
568 if (t == ':') {
569 if (unqual(p->type) != inttype
570 && unqual(p->type) != unsignedtype) {
571 error("`%t' is an illegal bit-field type\n",
572 p->type);
573 p->type = inttype;
575 t = gettok();
576 p->bitsize = intexpr(0, 0);
577 if (p->bitsize > 8*inttype->size || p->bitsize < 0) {
578 error("`%d' is an illegal bit-field size\n",
579 p->bitsize);
580 p->bitsize = 8*inttype->size;
581 } else if (p->bitsize == 0 && id) {
582 warning("extraneous 0-width bit field `%t %s' ignored\n", p->type, id);
584 p->name = stringd(genlabel(1));
586 p->lsb = 1;
588 else {
589 if (id == NULL)
590 error("field name missing\n");
591 else if (isfunc(p->type))
592 error("`%t' is an illegal field type\n", p->type);
593 else if (p->type->size == 0)
594 error("undefined size for field `%t %s'\n",
595 p->type, id);
597 if (isconst(p->type))
598 ty->u.sym->u.s.cfields = 1;
599 if (isvolatile(p->type))
600 ty->u.sym->u.s.vfields = 1;
601 n++;
602 if (Aflag >= 2 && n == 128)
603 warning("more than 127 fields in `%t'\n", ty);
604 if (t != ',')
605 break;
606 t = gettok();
608 test(';', stop);
610 { int bits = 0, off = 0, overflow = 0;
611 Field p, *q = &ty->u.sym->u.s.flist;
612 ty->align = IR->structmetric.align;
613 for (p = *q; p; p = p->link) {
614 int a = p->type->align ? p->type->align : 1;
615 if (p->lsb)
616 a = unsignedtype->align;
617 if (ty->op == UNION)
618 off = bits = 0;
619 else if (p->bitsize == 0 || bits == 0
620 || bits - 1 + p->bitsize > 8*unsignedtype->size) {
621 off = add(off, bits2bytes(bits-1));
622 bits = 0;
623 chkoverflow(off, a - 1);
624 off = roundup(off, a);
626 if (a > ty->align)
627 ty->align = a;
628 p->offset = off;
630 if (p->lsb) {
631 if (bits == 0)
632 bits = 1;
633 if (IR->little_endian)
634 p->lsb = bits;
635 else
636 p->lsb = 8*unsignedtype->size - bits + 1
637 - p->bitsize + 1;
638 bits += p->bitsize;
639 } else
640 off = add(off, p->type->size);
641 if (off + bits2bytes(bits-1) > ty->size)
642 ty->size = off + bits2bytes(bits-1);
643 if (p->name == NULL
644 || !('1' <= *p->name && *p->name <= '9')) {
645 *q = p;
646 q = &p->link;
649 *q = NULL;
650 chkoverflow(ty->size, ty->align - 1);
651 ty->size = roundup(ty->size, ty->align);
652 if (overflow) {
653 error("size of `%t' exceeds %d bytes\n", ty, inttype->u.sym->u.limits.max.i);
654 ty->size = inttype->u.sym->u.limits.max.i&(~(ty->align - 1));
657 static void funcdefn(int sclass, char *id, Type ty, Symbol params[], Coordinate pt) {
658 int i, n;
659 Symbol *callee, *caller, p;
660 Type rty = freturn(ty);
662 if (isstruct(rty) && rty->size == 0)
663 error("illegal use of incomplete type `%t'\n", rty);
664 for (n = 0; params[n]; n++)
666 if (n > 0 && params[n-1]->name == NULL)
667 params[--n] = NULL;
668 if (Aflag >= 2 && n > 31)
669 warning("more than 31 parameters in function `%s'\n", id);
670 if (ty->u.f.oldstyle) {
671 if (Aflag >= 1)
672 warning("old-style function definition for `%s'\n", id);
673 caller = params;
674 callee = newarray(n + 1, sizeof *callee, FUNC);
675 memcpy(callee, caller, (n+1)*sizeof *callee);
676 enterscope();
677 assert(level == PARAM);
678 while (kind[t] == STATIC || istypename(t, tsym))
679 decl(dclparam);
680 foreach(identifiers, PARAM, oldparam, callee);
682 for (i = 0; (p = callee[i]) != NULL; i++) {
683 if (!p->defined)
684 callee[i] = dclparam(0, p->name, inttype, &p->src);
685 *caller[i] = *p;
686 caller[i]->sclass = AUTO;
687 caller[i]->type = promote(p->type);
689 p = lookup(id, identifiers);
690 if (p && p->scope == GLOBAL && isfunc(p->type)
691 && p->type->u.f.proto) {
692 Type *proto = p->type->u.f.proto;
693 for (i = 0; caller[i] && proto[i]; i++) {
694 Type ty = unqual(proto[i]);
695 if (eqtype(isenum(ty) ? ty->type : ty,
696 unqual(caller[i]->type), 1) == 0)
697 break;
698 else if (isenum(ty) && !isenum(unqual(caller[i]->type)))
699 warning("compatibility of `%t' and `%t' is compiler dependent\n",
700 proto[i], caller[i]->type);
702 if (proto[i] || caller[i])
703 error("conflicting argument declarations for function `%s'\n", id);
706 else {
707 Type *proto = newarray(n + 1, sizeof *proto, PERM);
708 if (Aflag >= 1)
709 warning("missing prototype for `%s'\n", id);
710 for (i = 0; i < n; i++)
711 proto[i] = caller[i]->type;
712 proto[i] = NULL;
713 ty = func(rty, proto, 1);
715 } else {
716 callee = params;
717 caller = newarray(n + 1, sizeof *caller, FUNC);
718 for (i = 0; (p = callee[i]) != NULL && p->name; i++) {
719 NEW(caller[i], FUNC);
720 *caller[i] = *p;
721 if (isint(p->type))
722 caller[i]->type = promote(p->type);
723 caller[i]->sclass = AUTO;
724 if ('1' <= *p->name && *p->name <= '9')
725 error("missing name for parameter %d to function `%s'\n", i + 1, id);
728 caller[i] = NULL;
730 for (i = 0; (p = callee[i]) != NULL; i++)
731 if (p->type->size == 0) {
732 error("undefined size for parameter `%t %s'\n",
733 p->type, p->name);
734 caller[i]->type = p->type = inttype;
736 if (Aflag >= 2 && sclass != STATIC && strcmp(id, "main") == 0) {
737 if (ty->u.f.oldstyle)
738 warning("`%t %s()' is a non-ANSI definition\n", rty, id);
739 else if (!(rty == inttype
740 && (n == 0 && callee[0] == NULL
741 || n == 2 && callee[0]->type == inttype
742 && isptr(callee[1]->type) && callee[1]->type->type == charptype
743 && !variadic(ty))))
744 warning("`%s' is a non-ANSI definition\n", typestring(ty, id));
746 p = lookup(id, identifiers);
747 if (p && isfunc(p->type) && p->defined)
748 error("redefinition of `%s' previously defined at %w\n",
749 p->name, &p->src);
750 cfunc = dclglobal(sclass, id, ty, &pt);
751 cfunc->u.f.label = genlabel(1);
752 cfunc->u.f.callee = callee;
753 cfunc->u.f.pt = src;
754 cfunc->defined = 1;
755 if (xref)
756 use(cfunc, cfunc->src);
757 if (Pflag)
758 printproto(cfunc, cfunc->u.f.callee);
759 if (ncalled >= 0)
760 ncalled = findfunc(cfunc->name, pt.file);
761 labels = table(NULL, LABELS);
762 stmtlabs = table(NULL, LABELS);
763 refinc = 1.0;
764 regcount = 0;
765 codelist = &codehead;
766 codelist->next = NULL;
767 if (!IR->wants_callb && isstruct(rty))
768 retv = genident(AUTO, ptr(unqual(rty)), PARAM);
769 compound(0, NULL, 0);
771 definelab(cfunc->u.f.label);
772 if (events.exit)
773 apply(events.exit, cfunc, NULL);
774 walk(NULL, 0, 0);
775 exitscope();
776 assert(level == PARAM);
777 foreach(identifiers, level, checkref, NULL);
778 if (!IR->wants_callb && isstruct(rty)) {
779 Symbol *a;
780 a = newarray(n + 2, sizeof *a, FUNC);
781 a[0] = retv;
782 memcpy(&a[1], callee, (n+1)*sizeof *callee);
783 callee = a;
784 a = newarray(n + 2, sizeof *a, FUNC);
785 NEW(a[0], FUNC);
786 *a[0] = *retv;
787 memcpy(&a[1], caller, (n+1)*sizeof *callee);
788 caller = a;
790 if (!IR->wants_argb)
791 for (i = 0; caller[i]; i++)
792 if (isstruct(caller[i]->type)) {
793 caller[i]->type = ptr(caller[i]->type);
794 callee[i]->type = ptr(callee[i]->type);
795 caller[i]->structarg = callee[i]->structarg = 1;
797 if (glevel > 1) for (i = 0; callee[i]; i++) callee[i]->sclass = AUTO;
798 if (cfunc->sclass != STATIC)
799 (*IR->export)(cfunc);
800 if (glevel && IR->stabsym) {
801 swtoseg(CODE); (*IR->stabsym)(cfunc); }
802 swtoseg(CODE);
803 (*IR->function)(cfunc, caller, callee, cfunc->u.f.ncalls);
804 if (glevel && IR->stabfend)
805 (*IR->stabfend)(cfunc, lineno);
806 foreach(stmtlabs, LABELS, checklab, NULL);
807 exitscope();
808 expect('}');
809 labels = stmtlabs = NULL;
810 retv = NULL;
811 cfunc = NULL;
813 static void oldparam(Symbol p, void *cl) {
814 int i;
815 Symbol *callee = cl;
817 for (i = 0; callee[i]; i++)
818 if (p->name == callee[i]->name) {
819 callee[i] = p;
820 return;
822 error("declared parameter `%s' is missing\n", p->name);
824 void compound(int loop, struct swtch *swp, int lev) {
825 Code cp;
826 int nregs;
828 walk(NULL, 0, 0);
829 cp = code(Blockbeg);
830 enterscope();
831 assert(level >= LOCAL);
832 if (level == LOCAL && events.entry)
833 apply(events.entry, cfunc, NULL);
834 definept(NULL);
835 expect('{');
836 autos = registers = NULL;
837 if (level == LOCAL && IR->wants_callb
838 && isstruct(freturn(cfunc->type))) {
839 retv = genident(AUTO, ptr(unqual(freturn(cfunc->type))), level);
840 retv->defined = 1;
841 retv->ref = 1;
842 registers = append(retv, registers);
844 while (kind[t] == CHAR || kind[t] == STATIC
845 || istypename(t, tsym) && getchr() != ':')
846 decl(dcllocal);
848 int i;
849 Symbol *a = ltov(&autos, STMT);
850 nregs = length(registers);
851 for (i = 0; a[i]; i++)
852 registers = append(a[i], registers);
853 cp->u.block.locals = ltov(&registers, FUNC);
855 if (events.blockentry)
856 apply(events.blockentry, cp->u.block.locals, NULL);
857 while (kind[t] == IF || kind[t] == ID)
858 statement(loop, swp, lev);
859 walk(NULL, 0, 0);
860 foreach(identifiers, level, checkref, NULL);
862 int i = nregs, j;
863 Symbol p;
864 for ( ; (p = cp->u.block.locals[i]) != NULL; i++) {
865 for (j = i; j > nregs
866 && cp->u.block.locals[j-1]->ref < p->ref; j--)
867 cp->u.block.locals[j] = cp->u.block.locals[j-1];
868 cp->u.block.locals[j] = p;
871 if (level == LOCAL) {
872 Code cp;
873 for (cp = codelist; cp->kind < Label; cp = cp->prev)
875 if (cp->kind != Jump) {
876 if (freturn(cfunc->type) != voidtype) {
877 warning("missing return value\n");
878 retcode(cnsttree(inttype, 0L));
879 } else
880 retcode(NULL);
883 if (events.blockexit)
884 apply(events.blockexit, cp->u.block.locals, NULL);
885 cp->u.block.level = level;
886 cp->u.block.identifiers = identifiers;
887 cp->u.block.types = types;
888 code(Blockend)->u.begin = cp;
889 if (reachable(Gen))
890 definept(NULL);
891 if (level > LOCAL) {
892 exitscope();
893 expect('}');
896 static void checkref(Symbol p, void *cl) {
897 if (p->scope >= PARAM
898 && (isvolatile(p->type) || isfunc(p->type)))
899 p->addressed = 1;
900 if (Aflag >= 2 && p->defined && p->ref == 0) {
901 if (p->sclass == STATIC)
902 warning("static `%t %s' is not referenced\n",
903 p->type, p->name);
904 else if (p->scope == PARAM)
905 warning("parameter `%t %s' is not referenced\n",
906 p->type, p->name);
907 else if (p->scope >= LOCAL && p->sclass != EXTERN)
908 warning("local `%t %s' is not referenced\n",
909 p->type, p->name);
911 if (p->sclass == AUTO
912 && (p->scope == PARAM && regcount == 0
913 || p->scope >= LOCAL)
914 && !p->addressed && isscalar(p->type) && p->ref >= 3.0)
915 p->sclass = REGISTER;
916 if (level == GLOBAL && p->sclass == STATIC && !p->defined
917 && isfunc(p->type) && p->ref)
918 error("undefined static `%t %s'\n", p->type, p->name);
919 assert(!(level == GLOBAL && p->sclass == STATIC && !p->defined && !isfunc(p->type)));
921 static Symbol dcllocal(int sclass, char *id, Type ty, Coordinate *pos) {
922 Symbol p, q;
924 if (sclass == 0)
925 sclass = isfunc(ty) ? EXTERN : AUTO;
926 else if (isfunc(ty) && sclass != EXTERN) {
927 error("invalid storage class `%k' for `%t %s'\n",
928 sclass, ty, id);
929 sclass = EXTERN;
930 } else if (sclass == REGISTER
931 && (isvolatile(ty) || isstruct(ty) || isarray(ty))) {
932 warning("register declaration ignored for `%t %s'\n",
933 ty, id);
934 sclass = AUTO;
936 q = lookup(id, identifiers);
937 if (q && q->scope >= level
938 || q && q->scope == PARAM && level == LOCAL)
939 if (sclass == EXTERN && q->sclass == EXTERN
940 && eqtype(q->type, ty, 1))
941 ty = compose(ty, q->type);
942 else
943 error("redeclaration of `%s' previously declared at %w\n", q->name, &q->src);
945 assert(level >= LOCAL);
946 p = install(id, &identifiers, level, sclass == STATIC || sclass == EXTERN ? PERM : FUNC);
947 p->type = ty;
948 p->sclass = sclass;
949 p->src = *pos;
950 switch (sclass) {
951 case EXTERN: q = lookup(id, globals);
952 if (q == NULL || q->sclass == TYPEDEF || q->sclass == ENUM) {
953 q = lookup(id, externals);
954 if (q == NULL) {
955 q = install(p->name, &externals, GLOBAL, PERM);
956 q->type = p->type;
957 q->sclass = EXTERN;
958 q->src = src;
959 (*IR->defsymbol)(q);
962 if (!eqtype(p->type, q->type, 1))
963 warning("declaration of `%s' does not match previous declaration at %w\n", q->name, &q->src);
965 p->u.alias = q; break;
966 case STATIC: (*IR->defsymbol)(p);
967 initglobal(p, 0);
968 if (!p->defined)
969 if (p->type->size > 0) {
970 defglobal(p, BSS);
971 (*IR->space)(p->type->size);
972 } else
973 error("undefined size for `%t %s'\n",
974 p->type, p->name);
975 p->defined = 1; break;
976 case REGISTER: registers = append(p, registers);
977 regcount++;
978 p->defined = 1;
979 break;
980 case AUTO: autos = append(p, autos);
981 p->defined = 1;
982 if (isarray(ty))
983 p->addressed = 1; break;
984 default: assert(0);
986 if (t == '=') {
987 Tree e;
988 if (sclass == EXTERN)
989 error("illegal initialization of `extern %s'\n", id);
990 t = gettok();
991 definept(NULL);
992 if (isscalar(p->type)
993 || isstruct(p->type) && t != '{') {
994 if (t == '{') {
995 t = gettok();
996 e = expr1(0);
997 expect('}');
998 } else
999 e = expr1(0);
1000 } else {
1001 Symbol t1;
1002 Type ty = p->type, ty1 = ty;
1003 while (isarray(ty1))
1004 ty1 = ty1->type;
1005 if (!isconst(ty) && (!isarray(ty) || !isconst(ty1)))
1006 ty = qual(CONST, ty);
1007 t1 = genident(STATIC, ty, GLOBAL);
1008 initglobal(t1, 1);
1009 if (isarray(p->type) && p->type->size == 0
1010 && t1->type->size > 0)
1011 p->type = array(p->type->type,
1012 t1->type->size/t1->type->type->size, 0);
1013 e = idtree(t1);
1015 walk(root(asgn(p, e)), 0, 0);
1016 p->ref = 1;
1018 if (!isfunc(p->type) && p->defined && p->type->size <= 0)
1019 error("undefined size for `%t %s'\n", p->type, id);
1020 return p;
1022 void finalize(void) {
1023 foreach(externals, GLOBAL, doextern, NULL);
1024 foreach(identifiers, GLOBAL, doglobal, NULL);
1025 foreach(identifiers, GLOBAL, checkref, NULL);
1026 foreach(constants, CONSTANTS, doconst, NULL);
1028 static void doextern(Symbol p, void *cl) {
1029 (*IR->import)(p);
1031 static void doglobal(Symbol p, void *cl) {
1032 if (!p->defined && (p->sclass == EXTERN
1033 || isfunc(p->type) && p->sclass == AUTO))
1034 (*IR->import)(p);
1035 else if (!p->defined && !isfunc(p->type)
1036 && (p->sclass == AUTO || p->sclass == STATIC)) {
1037 if (isarray(p->type)
1038 && p->type->size == 0 && p->type->type->size > 0)
1039 p->type = array(p->type->type, 1, 0);
1040 if (p->type->size > 0) {
1041 defglobal(p, BSS);
1042 (*IR->space)(p->type->size);
1043 if (glevel > 0 && IR->stabsym)
1044 (*IR->stabsym)(p);
1045 } else
1046 error("undefined size for `%t %s'\n",
1047 p->type, p->name);
1048 p->defined = 1;
1050 if (Pflag
1051 && !isfunc(p->type)
1052 && !p->generated && p->sclass != EXTERN)
1053 printdecl(p, p->type);
1055 void doconst(Symbol p, void *cl) {
1056 if (p->u.c.loc) {
1057 assert(p->u.c.loc->u.seg == 0);
1058 defglobal(p->u.c.loc, LIT);
1059 if (isarray(p->type) && p->type->type == widechar) {
1060 unsigned int *s = p->u.c.v.p;
1061 int n = p->type->size/widechar->size;
1062 while (n-- > 0) {
1063 Value v;
1064 v.u = *s++;
1065 (*IR->defconst)(widechar->op, widechar->size, v);
1067 } else if (isarray(p->type))
1068 (*IR->defstring)(p->type->size, p->u.c.v.p);
1069 else
1070 (*IR->defconst)(p->type->op, p->type->size, p->u.c.v);
1071 p->u.c.loc = NULL;
1074 void checklab(Symbol p, void *cl) {
1075 if (!p->defined)
1076 error("undefined label `%s'\n", p->name);
1077 p->defined = 1;
1080 Type enumdcl(void) {
1081 char *tag;
1082 Type ty;
1083 Symbol p;
1084 Coordinate pos;
1086 t = gettok();
1087 pos = src;
1088 if (t == ID) {
1089 tag = token;
1090 t = gettok();
1091 } else
1092 tag = "";
1093 if (t == '{') {
1094 static char follow[] = { IF, 0 };
1095 int n = 0;
1096 long k = -1;
1097 List idlist = 0;
1098 ty = newstruct(ENUM, tag);
1099 t = gettok();
1100 if (t != ID)
1101 error("expecting an enumerator identifier\n");
1102 while (t == ID) {
1103 char *id = token;
1104 Coordinate s;
1105 if (tsym && tsym->scope == level)
1106 error("redeclaration of `%s' previously declared at %w\n",
1107 token, &tsym->src);
1108 s = src;
1109 t = gettok();
1110 if (t == '=') {
1111 t = gettok();
1112 k = intexpr(0, 0);
1113 } else {
1114 if (k == inttype->u.sym->u.limits.max.i)
1115 error("overflow in value for enumeration constant `%s'\n", id);
1116 k++;
1118 p = install(id, &identifiers, level, level < LOCAL ? PERM : FUNC);
1119 p->src = s;
1120 p->type = ty;
1121 p->sclass = ENUM;
1122 p->u.value = k;
1123 idlist = append(p, idlist);
1124 n++;
1125 if (Aflag >= 2 && n == 128)
1126 warning("more than 127 enumeration constants in `%t'\n", ty);
1127 if (t != ',')
1128 break;
1129 t = gettok();
1130 if (Aflag >= 2 && t == '}')
1131 warning("non-ANSI trailing comma in enumerator list\n");
1133 test('}', follow);
1134 ty->type = inttype;
1135 ty->size = ty->type->size;
1136 ty->align = ty->type->align;
1137 ty->u.sym->u.idlist = ltov(&idlist, PERM);
1138 ty->u.sym->defined = 1;
1139 } else if ((p = lookup(tag, types)) != NULL && p->type->op == ENUM) {
1140 ty = p->type;
1141 if (t == ';')
1142 error("empty declaration\n");
1143 } else {
1144 error("unknown enumeration `%s'\n", tag);
1145 ty = newstruct(ENUM, tag);
1146 ty->type = inttype;
1148 if (*tag && xref)
1149 use(p, pos);
1150 return ty;
1153 Type typename(void) {
1154 Type ty = specifier(NULL);
1156 if (t == '*' || t == '(' || t == '[') {
1157 ty = dclr(ty, NULL, NULL, 1);
1158 if (Aflag >= 1 && !hasproto(ty))
1159 warning("missing prototype\n");
1161 return ty;