|
|
1.1 root 1: /* C compiler: declaration parsing */
2:
3: #include "c.h"
4:
5:
6: Symbol cfunc = 0; /* current function */
7: char *fname = 0; /* current function name */
8: Symbol retv; /* return value location for structs */
9:
10: static List autos; /* auto locals for current block */
11: static int nglobals; /* number of external ids */
12: static int regcount; /* number of explicit register declarations */
13: static List registers; /* register locals for current block */
14:
15: dclproto(static void checklab,(Symbol, Generic));
16: dclproto(static void checkref,(Symbol, Generic));
17: dclproto(static Symbol dclglobal,(int, char *, Type, Coordinate *));
18: dclproto(static Symbol dcllocal,(int, char *, Type, Coordinate *));
19: dclproto(static Symbol dclparam,(int, char *, Type, Coordinate *));
20: dclproto(static void decl,(Symbol (*)(int, char *, Type, Coordinate *)));
21: dclproto(static void doglobal,(Symbol, Generic));
22: dclproto(static void doextern,(Symbol, Generic));
23: dclproto(static Type enumdecl,(void));
24: dclproto(static void fields,(Type));
25: dclproto(static Type structdcl,(int));
26: dclproto(static Type tnode,(int, Type));
27: dclproto(static Type type,(int, int *));
28: dclproto(static Type dclr,(Type, char **, Symbol **));
29: dclproto(static Type dclr1,(char **, Symbol **));
30: dclproto(static void funcdecl,(int, char *, Type, Symbol [], Coordinate));
31: dclproto(static void oldparam,(Symbol, Generic));
32: dclproto(static Symbol *parameters,(Type));
33: dclproto(static void exitparams,(Symbol []));
34: /* checklab - check for undefined labels; called at ends of functions */
35: static void checklab(p, cl) Symbol p; Generic cl; {
36: if (!p->defined)
37: error("undefined label `%s'\n", p->name);
38: p->defined = 1;
39: }
40:
41: /* checkref - check for unreferenced variables; called at ends of blocks */
42: static void checkref(p, cl) Symbol p; Generic cl; {
43: Symbol q;
44:
45: if (p->scope >= PARAM && isvolatile(p->type))
46: p->addressed = 1;
47: if (Aflag >= 2 && p->defined && p->ref == 0) {
48: if (p->sclass == STATIC)
49: warning("static `%t %s' is not referenced\n", p->type, p->name);
50: else if (p->scope == PARAM)
51: warning("parameter `%t %s' is not referenced\n", p->type, p->name);
52: else if (p->scope > PARAM && p->sclass != EXTERN)
53: warning("local `%t %s' is not referenced\n", p->type, p->name);
54: } else if (p->scope >= PARAM + (regcount > 0) && p->sclass == AUTO
55: && !p->addressed && isscalar(p->type) && p->ref >= 3.0)
56: p->sclass = REGISTER;
57: if (p->scope > PARAM && (q = lookup(p->name, externals))) {
58: q->ref += p->ref;
59: } else if (p->sclass == STATIC && !p->defined)
60: if (p->ref)
61: error("undefined static `%t %s'\n", p->type, p->name);
62: else if (isfunc(p->type))
63: warning("undefined static `%t %s'\n", p->type, p->name);
64: }
65:
66: /* compound - { ( decl ; )* statement* } */
67: void compound(loop, swp, lev) struct swtch *swp; {
68: Symbol p;
69: Code cp;
70: int i, j, nregs;
71:
72: walk(0, 0, 0);
73: cp = code(Blockbeg);
74: enterscope();
75: cp->u.block.bnumber = ++bnumber;
76: cp->u.block.level = level;
77: autos = registers = 0;
78: if (level == LOCAL && isstruct(freturn(cfunc->type))) {
79: retv = genident(AUTO, ptr(freturn(cfunc->type)), level);
80: retv->defined = 1;
81: retv->ref = 1;
82: registers = append(retv, registers); /* insures that retv is the 1st local */
83: }
84: if (level == LOCAL && events.entry)
85: apply(events.entry, (Generic)cfunc, (Generic)0);
86: expect('{');
87: while (kind[t] == CHAR || kind[t] == STATIC
88: || t == ID && tsym && tsym->sclass == TYPEDEF && (level < LOCAL || getchr() != ':'))
89: decl(dcllocal);
90: nregs = length(registers);
91: cp->u.block.locals = (Symbol *)ltoa(registers, (Generic *)talloc((nregs + length(autos) + 1)*sizeof(Symbol)));
92: ltoa(autos, (Generic *)&cp->u.block.locals[nregs]);
93: while (kind[t] == IF || kind[t] == ID)
94: statement(loop, swp, lev);
95: walk(0, 0, 0);
96: foreach(identifiers, level, checkref, (Generic)0);
97: for (i = nregs; p = cp->u.block.locals[i]; i++) {
98: for (j = i; j > nregs && cp->u.block.locals[j-1]->ref < p->ref; j--)
99: cp->u.block.locals[j] = cp->u.block.locals[j-1];
100: cp->u.block.locals[j] = p;
101: }
102: cp->u.block.identifiers = identifiers;
103: cp->u.block.types = types;
104: code(Blockend);
105: if (level > LOCAL) {
106: exitscope();
107: expect('}');
108: }
109: }
110:
111: /* dclglobal - called from decl to declare a global */
112: static Symbol dclglobal(sclass, id, ty, pos) char *id; Type ty; Coordinate *pos; {
113: Symbol p, q;
114:
115: if (!(sclass == 0 || sclass == EXTERN || sclass == STATIC)) {
116: error("invalid storage class `%k' for `%t %s'\n", sclass, ty, id);
117: sclass = 0;
118: }
119: if (sclass == 0)
120: sclass = AUTO;
121: if ((p = lookup(id, identifiers)) && p->scope == GLOBAL) {
122: if (p->sclass != TYPEDEF && eqtype(ty, p->type, 1))
123: ty = composite(ty, p->type);
124: else
125: error("redeclaration of `%s' previously declared at %w\n",
126: p->name, &p->src);
127: if (!isfunc(ty) && p->defined && t == '=')
128: error("redefinition of `%s' previously defined at %w\n",
129: p->name, &p->src);
130: if (p->sclass == STATIC && sclass == AUTO
131: || p->sclass != STATIC && sclass == STATIC)
132: warning("inconsistent linkage for `%s' previously declared at %w\n",
133: p->name, &p->src);
134: }
135: if (p == 0 || p->scope != GLOBAL)
136: p = install(id, &globals, 1);
137: p->type = ty;
138: if (p->sclass == 0 || sclass != EXTERN && p->sclass != STATIC)
139: p->sclass = sclass;
140: if (p->sclass != STATIC) {
141: nglobals++;
142: if (Aflag >= 2 && nglobals == 512)
143: warning("more than 511 external identifiers\n");
144: }
145: p->src = *pos;
146: if (!p->defined)
147: (*IR->defsymbol)(p);
148: if (q = lookup(p->name, externals)) {
149: if ((p->sclass == AUTO ? EXTERN : p->sclass) != q->sclass
150: || !eqtype(p->type, q->type, 1))
151: warning("declaration of `%s' does not match previous declaration at %w\n",
152: p->name, &q->src);
153: p->ref += q->ref;
154: }
155: if (!isfunc(p->type))
156: initglobal(p, 0);
157: else if (t == '=') {
158: error("illegal initialization for `%s'\n", p->name);
159: t = gettok();
160: initializer(p->type, 0);
161: }
162: return p;
163: }
164:
165: /* dcllocal - called from decl to declare a local */
166: static Symbol dcllocal(sclass, id, ty, pos) char *id; Type ty; Coordinate *pos; {
167: Symbol p, q;
168:
169: if (isfunc(ty)) {
170: if (!(sclass == 0 || sclass == EXTERN))
171: error("invalid storage class `%k' for `%t %s'\n", sclass, ty, id);
172: sclass = EXTERN;
173: } else if (sclass == 0)
174: sclass = AUTO;
175: if (sclass == REGISTER && (isvolatile(ty) || isstruct(ty) || isarray(ty))) {
176: warning("register declaration ignored for `%t %s'\n", ty, id);
177: sclass = AUTO;
178: }
179: if ((q = lookup(id, identifiers))
180: && (q->scope >= level || q->scope == PARAM && level == PARAM+1))
181: if (sclass == EXTERN && q->sclass == EXTERN && eqtype(q->type, ty, 1))
182: ty = composite(ty, q->type);
183: else
184: error("redeclaration of `%s' previously declared at %w\n",
185: q->name, &q->src);
186: assert(level >= LOCAL);
187: p = install(id, &identifiers, 0);
188: p->type = ty;
189: p->sclass = sclass;
190: p->src = *pos;
191: switch (sclass) {
192: case EXTERN: {
193: Symbol r;
194: if (q && q->scope == GLOBAL && q->sclass == STATIC) {
195: p->sclass = STATIC;
196: p->scope = GLOBAL;
197: (*IR->defsymbol)(p);
198: p->scope = level;
199: } else
200: (*IR->defsymbol)(p);
201: if ((r = lookup(id, externals)) == 0) {
202: r = install(p->name, &externals, 1);
203: r->src = p->src;
204: r->type = p->type;
205: r->sclass = p->sclass;
206: if ((q = lookup(id, globals)) && q->sclass != TYPEDEF && q->sclass != ENUM)
207: r = q;
208: }
209: if (r && ((r->sclass == AUTO ? EXTERN : r->sclass) != p->sclass
210: || !eqtype(r->type, p->type, 1)))
211: warning("declaration of `%s' does not match previous declaration at %w\n",
212: r->name, &r->src);
213: break;
214: }
215: case STATIC:
216: (*IR->defsymbol)(p);
217: initglobal(p, 0);
218: if (!p->defined)
219: if (p->type->size > 0) {
220: defglobal(p, BSS);
221: (*IR->space)(p->type->size);
222: } else
223: error("undefined size for `%t %s'\n", p->type, p->name);
224: p->defined = 1;
225: break;
226: case REGISTER:
227: registers = append(p, registers);
228: regcount++;
229: p->defined = 1;
230: break;
231: case AUTO:
232: autos = append(p, autos);
233: p->defined = 1;
234: break;
235: default: assert(0);
236: }
237: if (t == '=') {
238: Tree e;
239: if (sclass == EXTERN)
240: error("illegal initialization of `extern %s'\n", id);
241: t = gettok();
242: definept(0);
243: if (isscalar(p->type) || isstruct(p->type) && t != '{') {
244: if (t == '{') {
245: t = gettok();
246: e = constexpr(0);
247: genconst(e, 0);
248: expect('}');
249: } else
250: e = expr1(0);
251: } else {
252: Type ty = p->type;
253: if (!isconst(ty) && (!isarray(ty) || !isconst(ty->type)))
254: ty = qual(CONST, ty);
255: q = genident(STATIC, ty, GLOBAL);
256: initglobal(q, 1);
257: if (isarray(p->type) && p->type->size == 0 && q->type->size > 0)
258: p->type = array(p->type->type, q->type->size/q->type->type->size, 0);
259: e = idnode(q);
260: }
261: walk(root(asgn(p, e)), 0, 0);
262: p->ref = 1;
263: }
264: if (p->sclass == AUTO && isarray(p->type) && p->type->type->size > 0
265: && p->type->align < IR->structmetric.align)
266: p->type = array(p->type->type,
267: p->type->size/p->type->type->size, IR->structmetric.align);
268: if (!isfunc(p->type) && p->defined && p->type->size <= 0)
269: error("undefined size for `%t %s'\n", p->type, id);
270: return p;
271: }
272:
273: /* dclparam - called from decl to declare a parameter */
274: static Symbol dclparam(sclass, id, ty, pos) char *id; Type ty; Coordinate *pos; {
275: Symbol p;
276:
277: if ((p = lookup(id, identifiers)) && p->scope == level)
278: error("duplicate declaration for `%s' previously declared at %w\n",
279: id, &p->src);
280: else if (p == 0 || p->scope < level)
281: p = install(id, &identifiers, 0);
282: if (isfunc(ty))
283: ty = ptr(ty);
284: else if (isarray(ty))
285: ty = atop(ty);
286: if (!(sclass == 0 || sclass == AUTO || sclass == REGISTER)) {
287: error("invalid storage class `%k' for `%t %s'\n", sclass, ty, id);
288: sclass = AUTO;
289: }
290: if (sclass == REGISTER && (isvolatile(ty) || isstruct(ty))) {
291: warning("register declaration ignored for `%t%s\n", ty,
292: stringf(id ? " %s'" : "' parameter", id));
293: sclass = AUTO;
294: }
295: if (sclass == 0)
296: sclass = AUTO;
297: p->sclass = sclass;
298: p->src = *pos;
299: p->type = ty;
300: p->defined = 1;
301: if (t == '=') {
302: error("illegal initialization for parameter `%s'\n", id);
303: t = gettok();
304: expr1(0);
305: }
306: return p;
307: }
308: /* dclr - declarator */
309: static Type dclr(basety, id, params) Type basety; char **id; Symbol **params; {
310: Type ty;
311:
312: for (ty = dclr1(id, params); ty; ty = ty->type)
313: switch (ty->op) {
314: case POINTER:
315: basety = ptr(basety);
316: break;
317: case FUNCTION:
318: basety = func(basety, ty->u.f.proto, ty->u.f.oldstyle);
319: break;
320: case ARRAY:
321: basety = array(basety, ty->size, 0);
322: break;
323: case CONST: case VOLATILE:
324: basety = qual(ty->op, basety);
325: break;
326: default:
327: assert(0);
328: }
329: if (Aflag >= 2 && basety->size > 32767)
330: warning("more than 32767 bytes in `%t'\n", basety);
331: return basety;
332: }
333:
334: /* dclr1 - ( id | * ( const | volatile )* | '(' dclr1 ')' ) ( (...) | [...] )* */
335: static Type dclr1(id, params) char **id; Symbol **params; {
336: Type ty = 0;
337:
338: switch (t) {
339: case ID:
340: if (id)
341: *id = token;
342: else
343: error("extraneous identifier `%s'\n", token);
344: t = gettok();
345: break;
346: case '*':
347: t = gettok();
348: if (t == CONST || t == VOLATILE) {
349: Type ty1;
350: ty1 = ty = tnode(t, (Type)0);
351: while ((t = gettok()) == CONST || t == VOLATILE)
352: ty1 = tnode(t, ty1);
353: ty->type = dclr1(id, params);
354: ty = ty1;
355: } else
356: ty = dclr1(id, params);
357: ty = tnode(POINTER, ty);
358: break;
359: case '(':
360: t = gettok();
361: if (kind[t] == CHAR || t == ID && tsym && tsym->sclass == TYPEDEF) {
362: Symbol *args;
363: ty = tnode(FUNCTION, ty);
364: enterscope();
365: args = parameters(ty);
366: exitparams(args);
367: } else {
368: ty = dclr1(id, params);
369: expect(')');
370: if (ty == 0 && id == 0)
371: return tnode(FUNCTION, ty);
372: }
373: break;
374: case '[':
375: break;
376: default:
377: return ty;
378: }
379: while (t == '(' || t == '[')
380: if (t == '(') {
381: Symbol *args;
382: t = gettok();
383: ty = tnode(FUNCTION, ty);
384: enterscope();
385: args = parameters(ty);
386: if (params && *params == 0)
387: *params = args;
388: else
389: exitparams(args);
390: } else {
391: int n = 0;
392: t = gettok();
393: if (kind[t] == ID) {
394: n = intexpr(']', 1);
395: if (n <= 0) {
396: error("`%d' is an illegal array size\n", n);
397: n = 1;
398: }
399: } else
400: expect(']');
401: ty = tnode(ARRAY, ty);
402: ty->size = n;
403: }
404: return ty;
405: }
406:
407: /* decl - type [ dclr ( , dclr )* ] ; */
408: static void decl(dcl)
409: dclproto(Symbol (*dcl),(int, char *, Type, Coordinate *)); {
410: int sclass;
411: char *id = 0;
412: Type ty, ty1;
413: Coordinate pt;
414: static char follow[] = { CHAR, STATIC, ID, 0 };
415:
416: pt = src;
417: ty = type(level, &sclass);
418: if (t == ID || t == '*' || t == '(' || t == '[') {
419: Coordinate pos;
420: pos = src;
421: if (level == GLOBAL) {
422: Symbol *params = 0;
423: ty1 = dclr(ty, &id, ¶ms);
424: if (params && id && isfunc(ty1)
425: && (t == '{' || kind[t] == CHAR
426: || (kind[t] == STATIC && t != TYPEDEF)
427: || t == ID && tsym && tsym->sclass == TYPEDEF)) {
428: if (sclass == TYPEDEF) {
429: error("invalid use of `typedef'\n");
430: sclass = EXTERN;
431: }
432: if (ty1->u.f.oldstyle)
433: exitscope();
434: funcdecl(sclass, fname = id, ty1, params, pt);
435: fname = 0;
436: return;
437: } else if (params)
438: exitparams(params);
439: } else
440: ty1 = dclr(ty, &id, (Symbol **)0);
441: for (;;) {
442: if (Aflag >= 1 && !hasproto(ty1))
443: warning("missing prototype\n");
444: if (id == 0)
445: error("missing identifier\n");
446: else if (sclass == TYPEDEF)
447: deftype(id, ty1, &pos);
448: else
449: (*dcl)(sclass, id, ty1, &pos);
450: if (level == GLOBAL)
451: tfree();
452: if (t != ',')
453: break;
454: t = gettok();
455: id = 0;
456: pos = src;
457: ty1 = dclr(ty, &id, (Symbol **)0);
458: }
459: } else if (ty == 0 || !(isenum(ty)
460: || isstruct(ty) && (*ty->u.sym->name < '1' || *ty->u.sym->name > '9')))
461: error("empty declaration\n");
462: test(';', follow);
463: }
464:
465: /* doextern - import external declared in a block, if necessary, propagate flags */
466: static void doextern(p, cl) Symbol p; Generic cl; {
467: Symbol q;
468:
469: if (q = lookup(p->name, identifiers))
470: q->ref += p->ref;
471: else {
472: (*IR->defsymbol)(p);
473: (*IR->import)(p);
474: }
475: }
476:
477: /* doglobal - finalize tentative definitions, check for imported symbols */
478: static void doglobal(p, cl) Symbol p; Generic cl; {
479: if (p->sclass == TYPEDEF || p->sclass == ENUM || p->defined) {
480: if (Pflag && !isfunc(p->type) && !p->generated)
481: printdecl(p, p->type);
482: return;
483: }
484: if (p->sclass == EXTERN || isfunc(p->type))
485: (*IR->import)(p);
486: else if (!isfunc(p->type)) {
487: if (isarray(p->type) && p->type->size == 0
488: && p->type->type->size > 0)
489: p->type = array(p->type->type, 1, 0);
490: if (p->type->size > 0) {
491: defglobal(p, BSS);
492: (*IR->space)(p->type->size);
493: } else
494: error("undefined size for `%t %s'\n", p->type, p->name);
495: p->defined = 1;
496: if (Pflag && !p->generated)
497: printdecl(p, p->type);
498: }
499: }
500:
501: /* enumdecl - enum [ id ] [ { id [ = cexpr ] ( , id [ = cexpr ] )* } ] */
502: static Type enumdecl() {
503: char *tag;
504: Type ty;
505: Symbol p;
506: Coordinate pos;
507:
508: t = gettok();
509: if (t == ID) {
510: tag = token;
511: pos = src;
512: t = gettok();
513: } else
514: tag = string("");
515: if (t == '{') {
516: static char follow[] = { IF, 0 };
517: int n = 0, k = -1;
518: List idlist = 0;
519: ty = newstruct(ENUM, tag);
520: t = gettok();
521: if (t != ID)
522: error("expecting an enumerator identifier\n");
523: while (t == ID) {
524: char *id = token;
525: Coordinate s;
526: if (tsym && tsym->scope == level)
527: error("redeclaration of `%s' previously declared at %w\n",
528: token, &tsym->src);
529: s = src;
530: t = gettok();
531: if (t == '=') {
532: t = gettok();
533: k = intexpr(0, 0);
534: } else {
535: if (k == INT_MAX)
536: error("overflow in value for enumeration constant `%s'\n", p->name);
537: k++;
538: }
539: p = install(id, &identifiers, level < LOCAL);
540: p->src = s;
541: p->type = ty;
542: p->sclass = ENUM;
543: p->u.value = k;
544: idlist = append(p, idlist);
545: n++;
546: if (Aflag >= 2 && n == 128)
547: warning("more than 127 enumeration constants in `%t'\n", ty);
548: if (t != ',')
549: break;
550: t = gettok();
551: if (Aflag >= 2 && t == '}')
552: warning("non-ANSI trailing comma in enumerator list\n");
553: }
554: test('}', follow);
555: ty->type = inttype;
556: ty->size = ty->type->size;
557: ty->align = ty->type->align;
558: ty->u.sym->u.idlist = (Symbol *)ltoa(idlist, (Generic *)alloc((length(idlist) + 1)*sizeof(Symbol)));
559: ty->u.sym->defined = 1;
560: } else if ((p = lookup(tag, types)) && p->type->op == ENUM) {
561: if (*tag && xref)
562: use(p, pos);
563: ty = p->type;
564: } else {
565: error("unknown enumeration `%s'\n", tag);
566: ty = newstruct(ENUM, tag);
567: ty->type = inttype;
568: }
569: return ty;
570: }
571:
572: /* fields - ( type dclr ( , dclr )* ; )* */
573: static void fields(ty) Type ty; {
574: int n = 0, bits, off, overflow = 0;
575: Field p, *q;
576:
577: while (kind[t] == CHAR
578: || t == ID && tsym && tsym->sclass == TYPEDEF) {
579: static char follow[] = { IF, CHAR, '}', 0 };
580: Type ty1 = type(0, (int *)0);
581: do {
582: char *id = 0;
583: Type fty;
584: if ((fty = dclr(ty1, &id, (Symbol **)0)) == 0)
585: fty = ty1;
586: if (Aflag >= 1 && !hasproto(fty))
587: warning("missing prototype\n");
588: p = newfield(id, ty, fty); /* refme */
589: if (t == ':') {
590: fty = unqual(fty);
591: if (isenum(fty))
592: fty = fty->type;
593: if (fty != inttype && fty != unsignedtype) {
594: error("`%t' is an illegal bit field type\n", p->type);
595: p->type = inttype;
596: }
597: t = gettok();
598: p->bitsize = intexpr(0, 0);
599: if (p->bitsize > 8*inttype->size || p->bitsize < 0) {
600: error("`%d' is an illegal bit field size\n", p->bitsize);
601: p->bitsize = 8*inttype->size;
602: } else if (p->bitsize == 0 && id) {
603: warning("extraneous 0-width bit field `%t %s' ignored\n",
604: p->type, id);
605: p->name = stringd(genlabel(1));
606: }
607: p->lsb = 1;
608: } else if (id == 0 && isstruct(p->type)) {
609: if (Aflag >= 2)
610: warning("non-ANSI unnamed substructure in `%t'\n", ty);
611: if (p->type->size == 0)
612: error("undefined size for field `%t'\n", p->type);
613: p->name = 0;
614: break;
615: } else {
616: if (id == 0)
617: error("field name missing\n");
618: else if (p->type->size == 0)
619: error("undefined size for field `%t %s'\n", p->type, id);
620: }
621: n++;
622: if (Aflag >= 2 && n == 128)
623: warning("more than 127 fields in `%t'\n", ty);
624: } while (t == ',' && (t = gettok()));
625: test(';', follow);
626: }
627: ty->align = IR->structmetric.align;
628: off = bits = 0;
629: #define add(x,n) (x > INT_MAX - (n) ? (overflow = 1, x) : x + n)
630: q = &ty->u.sym->u.s.flist;
631: for (p = *q; p; p = p->link) {
632: int a = p->type->align ? p->type->align : 1;
633: if (ty->op == UNION) {
634: if (p->lsb)
635: a = unsignedtype->align;
636: bits = 0;
637: } else if (bits == 0 || p->bitsize == 0
638: || bits - 1 + p->bitsize > 8*unsignedtype->size) {
639: if (bits)
640: off = add(off, (bits + 6)/8);
641: if (p->lsb)
642: a = unsignedtype->align;
643: add(off, a - 1);
644: off = roundup(off, a);
645: bits = 0;
646: }
647: if (a > ty->align)
648: ty->align = a;
649: p->offset = off;
650: if (p->lsb) {
651: if (bits == 0)
652: bits = 1;
653: if (IR->little_endian)
654: p->lsb = bits;
655: else
656: p->lsb = 8*unsignedtype->size - bits - p->bitsize + 2;
657: bits += p->bitsize;
658: if (ty->op == UNION && (bits + 6)/8 > ty->size)
659: ty->size = (bits + 6)/8;
660: } else if (ty->op == STRUCT)
661: off = add(off, p->type->size);
662: else if (p->type->size > ty->size)
663: ty->size = p->type->size;
664: if (isconst(p->type))
665: ty->u.sym->u.s.cfields = 1;
666: if (isvolatile(p->type))
667: ty->u.sym->u.s.vfields = 1;
668: if (p->name == 0 || *p->name > '9') {
669: *q = p;
670: q = &p->link;
671: }
672: }
673: *q = 0;
674: if (bits)
675: off = add(off, (bits + 6)/8);
676: if (ty->op == STRUCT)
677: ty->size = off;
678: else if (off > ty->size)
679: ty->size = off;
680: add(ty->size, ty->align - 1);
681: ty->size = roundup(ty->size, ty->align);
682: if (overflow) {
683: error("size of `%t' exceeds %d bytes\n", ty, INT_MAX);
684: ty->size = INT_MAX&(~(ty->align - 1));
685: }
686: checkfields(ty);
687: }
688:
689: /* finalize - finalize tentative definitions, constants, check unref'd statics */
690: void finalize() {
691: if (xref) {
692: setuses(identifiers);
693: foreach(types, level, fielduses, (Generic)0);
694: setuses(types);
695: }
696: foreach(identifiers, GLOBAL, doglobal, (Generic)0);
697: foreach(externals, GLOBAL, doextern, (Generic)0);
698: foreach(identifiers, GLOBAL, checkref, (Generic)0);
699: foreach(constants, CONSTANTS, doconst, (Generic)0);
700: }
701: /* funcdecl - ... ( ... ) decl* compound */
702: static void funcdecl(sclass, id, ty, params, pt) char *id; Type ty; Symbol params[]; Coordinate pt; {
703: int i, n;
704: Code rp;
705: Symbol *callee, *caller, p;
706:
707: regcount = 0;
708: if (isstruct(freturn(ty)) && freturn(ty)->size == 0)
709: error("illegal use of incomplete type `%t'\n", freturn(ty));
710: for (n = 0; params[n]; n++)
711: ;
712: if (n > 0 && params[n-1]->name == 0)
713: params[--n] = 0;
714: if (Aflag >= 2 && n > 31)
715: warning("more than 31 parameters in function `%s'\n", id);
716: if (!ty->u.f.oldstyle) {
717: callee = params;
718: caller = (Symbol *)talloc((n + 1)*sizeof *caller);
719: for (i = 0; (p = callee[i]) && p->name; i++) {
720: caller[i] = (Symbol)talloc(sizeof *caller[i]);
721: *caller[i] = *p;
722: caller[i]->type = promote(callee[i]->type);
723: if (callee[i]->sclass == REGISTER) {
724: caller[i]->sclass = AUTO;
725: ++regcount;
726: }
727: if (*p->name >= '1' && *p->name <= '9')
728: error("missing parameter name to function `%s'\n", id);
729: }
730: caller[i] = 0;
731:
732: } else {
733: Type *proto;
734: enterscope();
735: caller = params;
736: while (kind[t] == CHAR || kind[t] == STATIC
737: || t == ID && tsym && tsym->sclass == TYPEDEF)
738: decl(dclparam);
739: callee = (Symbol *)talloc((n + 1)*sizeof *callee);
740: for (i = 0; i < n; i++)
741: callee[i] = caller[i];
742: callee[i] = 0;
743: foreach(identifiers, PARAM, oldparam, (Generic)callee);
744: for (i = 0; p = callee[i]; i++) {
745: if (!p->defined)
746: callee[i] = dclparam(AUTO, p->name, inttype, &p->src);
747: *caller[i] = *p;
748: if (p->sclass == REGISTER) {
749: caller[i]->sclass = AUTO;
750: ++regcount;
751: }
752: if (unqual(p->type) == floattype)
753: caller[i]->type = doubletype;
754: else
755: caller[i]->type = promote(p->type);
756: }
757: if ((p = lookup(id, identifiers)) && p->scope == GLOBAL
758: && isfunc(p->type) && p->type->u.f.proto) {
759: proto = p->type->u.f.proto;
760: for (i = 0; caller[i] && proto[i]; i++)
761: if (eqtype(unqual(proto[i]), unqual(caller[i]->type), 1) == 0)
762: break;
763: if (proto[i] || caller[i])
764: error("conflicting argument declarations for function `%s'\n", id);
765: ty = func(freturn(ty), proto, 0);
766: } else {
767: proto = (Type *)alloc((n + 1)*sizeof *proto);
768: for (i = 0; i < n; i++)
769: if (callee[i]->type == floattype)
770: proto[i] = doubletype;
771: else
772: proto[i] = promote(callee[i]->type);
773: proto[i] = 0;
774: ty = func(freturn(ty), proto, 1);
775: }
776: }
777: if (Aflag >= 1 && !hasproto(ty))
778: warning("missing prototype\n");
779: for (i = 0; p = callee[i]; i++)
780: if (p->type->size == 0) {
781: error("undefined size for parameter `%t %s'\n", p->type, p->name);
782: caller[i]->type = p->type = inttype;
783: }
784: if ((p = lookup(id, identifiers)) && isfunc(p->type)) {
785: if (p->defined)
786: error("redefinition of `%s' previously defined at %w\n",
787: p->name, &p->src);
788: if (xref)
789: use(p, p->src);
790: }
791: cfunc = dclglobal(sclass, id, ty, &pt);
792: cfunc->u.f.pt[0] = pt;
793: if (IR->jump_on_return || glevel > 1)
794: cfunc->u.f.label = genlabel(1);
795: cfunc->u.f.callee = callee;
796: cfunc->defined = 1;
797: if (Pflag)
798: printproto(cfunc, cfunc->u.f.callee);
799: labels[0] = table(0, LABELS);
800: labels[1] = table(0, LABELS);
801: refinc = 1.0;
802: bnumber = -1;
803: codelist = &codehead;
804: codelist->next = 0;
805: if (ncalled >= 0)
806: ncalled = findfunc(cfunc->name, pt.file);
807: cfunc->u.f.pt[2] = definept(0)->u.point.src;
808: compound(0, (struct swtch *)0, 0);
809: for (rp = codelist; rp->kind < Label; rp = rp->prev)
810: ;
811: if (rp->kind != Jump) {
812: if (cfunc->u.f.label == 0)
813: definept(0);
814: if (freturn(cfunc->type) != voidtype
815: && (freturn(cfunc->type) != inttype || Aflag >= 1))
816: warning("missing return value\n");
817: retcode(0, 0);
818: }
819: if (cfunc->u.f.label) {
820: definelab(cfunc->u.f.label);
821: definept(0);
822: walk(0, 0, 0);
823: }
824: exitscope();
825: foreach(identifiers, level, checkref, (Generic)0);
826: flushequ();
827: swtoseg(CODE);
828: if (cfunc->sclass != STATIC)
829: (*IR->export)(cfunc);
830: if (glevel && IR->stabsym) {
831: (*IR->stabsym)(cfunc);
832: swtoseg(CODE);
833: }
834: for (i = 0; caller[i]; i++) {
835: if (glevel > 1)
836: callee[i]->sclass = AUTO;
837: if (IR->no_argb && isstruct(caller[i]->type)) {
838: caller[i]->type = ptr(caller[i]->type);
839: callee[i]->type = ptr(callee[i]->type);
840: caller[i]->structarg = callee[i]->structarg = 1;
841: }
842: }
843: (*IR->function)(cfunc, caller, callee, cfunc->u.f.ncalls);
844: if (glevel && IR->stabfend)
845: (*IR->stabfend)(cfunc, lineno);
846: outflush();
847: cfunc->u.f.pt[1] = src;
848: expect('}');
849: setuses(labels[0]);
850: foreach(labels[0], LABELS, checklab, (Generic)0);
851: if (events.exit)
852: apply(events.exit, (Generic)cfunc, (Generic)0);
853: exitscope();
854: retv = 0;
855: tfree();
856: cfunc = 0;
857: }
858: /* oldparam - check that p is an old-style parameter, and patch callee[i] */
859: static void oldparam(p, cl) Symbol p; Generic cl; {
860: Symbol *callee = (Symbol *)cl;
861: int i;
862:
863: for (i = 0; callee[i]; i++)
864: if (p->name == callee[i]->name) {
865: callee[i] = p;
866: return;
867: }
868: error("declared parameter `%s' is missing\n", p->name);
869: }
870: /* parameters - [id ( , id )* | type dclr ( , type dclr )*] */
871: static Symbol *parameters(fty) Type fty; {
872: List list = 0;
873: Symbol *params;
874:
875: if (kind[t] == CHAR || kind[t] == STATIC
876: || t == ID && tsym && tsym->sclass == TYPEDEF) {
877: int n = 0, sclass;
878: Type last = 0, ty;
879: static struct symbol sentinel;
880: if (sentinel.type == 0) {
881: sentinel.type = voidtype;
882: sentinel.defined = 1;
883: }
884: for (;;) {
885: char *id = 0;
886: if (last && t == ELLIPSIS) {
887: if (last == voidtype)
888: error("illegal formal parameter types\n");
889: list = append(&sentinel, list);
890: t = gettok();
891: break;
892: }
893: if (t == ID && (tsym == 0 || tsym->sclass != TYPEDEF)
894: || t != ID && t != REGISTER && kind[t] != CHAR)
895: error("missing parameter type\n");
896: n++;
897: ty = dclr(type(PARAM, &sclass), &id, (Symbol **)0);
898: if (Aflag >= 1 && !hasproto(ty))
899: warning("missing prototype\n");
900: if (ty == voidtype && (last || id))
901: error("illegal formal parameter types\n");
902: if (id == 0)
903: id = stringd(n);
904: if (ty != voidtype)
905: list = append(dclparam(sclass, id, ty, &src), list);
906: last = ty;
907: if (t != ',')
908: break;
909: t = gettok();
910: }
911: fty->u.f.proto = (Type *)alloc((length(list) + 1)*sizeof (Type *));
912: params = (Symbol *)ltoa(list, (Generic *)0);
913: for (n = 0; params[n]; n++)
914: fty->u.f.proto[n] = params[n]->type;
915: fty->u.f.proto[n] = 0;
916: fty->u.f.oldstyle = 0;
917: } else {
918: if (t == ID)
919: for (;;) {
920: Symbol p;
921: if (t != ID) {
922: error("expecting an identifier\n");
923: break;
924: }
925: p = dclparam(AUTO, token, inttype, &src);
926: p->defined = 0;
927: list = append(p, list);
928: t = gettok();
929: if (t != ',')
930: break;
931: t = gettok();
932: }
933: params = (Symbol *)ltoa(list, (Generic *)0);
934: fty->u.f.proto = 0;
935: fty->u.f.oldstyle = 1;
936: }
937: if (t != ')') {
938: static char follow[] = { CHAR, STATIC, IF, ')', 0 };
939: expect(')');
940: skipto('{', follow);
941: }
942: if (t == ')')
943: t = gettok();
944: return params;
945: }
946: static void exitparams(params) Symbol params[]; {
947: if (params[0] && !params[0]->defined)
948: error("extraneous old-style parameter list\n");
949: exitscope();
950: }
951:
952: /* program - decl* */
953: void program() {
954: int n;
955:
956: level = GLOBAL;
957: for (n= 0; t != EOI; n++)
958: if (kind[t] == CHAR || kind[t] == STATIC || t == ID)
959: decl(dclglobal);
960: else {
961: if (t == ';')
962: warning("empty declaration\n");
963: else
964: error("unrecognized declaration\n");
965: t = gettok();
966: }
967: if (n == 0)
968: warning("empty input file\n");
969: }
970:
971: /* structdcl - ( struct | union ) ( [ id ] { ( field; )+ } | id ) */
972: static Type structdcl(op) {
973: char *tag;
974: Type ty;
975: Symbol p;
976: Coordinate pos;
977:
978: t = gettok();
979: if (t == ID) {
980: tag = token;
981: pos = src;
982: t = gettok();
983: } else
984: tag = string("");
985: if (t == '{') {
986: static char follow[] = { IF, ',', 0 };
987: ty = newstruct(op, tag);
988: if (*tag)
989: ty->u.sym->src = pos;
990: t = gettok();
991: if (kind[t] == CHAR || t == ID && tsym
992: && tsym->sclass == TYPEDEF)
993: fields(ty);
994: else
995: error("invalid %k field declarations\n", op);
996: test('}', follow);
997: ty->u.sym->defined = 1;
998: } else if (*tag && (p = lookup(tag, types)) && p->type->op == op) {
999: if (t == ';' && p->scope < level)
1000: ty = newstruct(op, tag);
1001: if (xref)
1002: use(p, pos);
1003: ty = p->type;
1004: } else {
1005: if (*tag == 0)
1006: error("missing %k tag\n", op);
1007: ty = newstruct(op, tag);
1008: if (*tag && xref)
1009: use(ty->u.sym, pos);
1010: }
1011: return ty;
1012: }
1013:
1014: /* tnode - allocate a type node */
1015: static Type tnode(op, type) Type type; {
1016: Type ty = (Type) talloc(sizeof *ty);
1017:
1018: BZERO(ty, struct tynode);
1019: ty->op = op;
1020: ty->type = type;
1021: return ty;
1022: }
1023:
1024: /* type - parse basic storage class and type specification */
1025: static Type type(lev, sclass) int *sclass; {
1026: int cls, cons, *p, sign, size, tt, type, vol;
1027: Type ty = 0;
1028:
1029: if (sclass == 0)
1030: cls = AUTO;
1031: else
1032: *sclass = 0;
1033: for (vol = cons = sign = size = type = 0;;) {
1034: p = &type;
1035: tt = t;
1036: switch (t) {
1037: case AUTO: case REGISTER: case STATIC:
1038: case EXTERN: case TYPEDEF:
1039: p = sclass ? sclass : &cls;
1040: break;
1041: case CONST:
1042: p = &cons;
1043: break;
1044: case VOLATILE:
1045: p = &vol;
1046: break;
1047: case SIGNED: case UNSIGNED:
1048: p = &sign;
1049: break;
1050: case LONG: case SHORT:
1051: p = &size;
1052: break;
1053: case VOID: case CHAR: case INT: case FLOAT: case DOUBLE:
1054: ty = tsym->type;
1055: break;
1056: case ENUM:
1057: ty = enumdecl();
1058: break;
1059: case STRUCT: case UNION:
1060: ty = structdcl(t);
1061: break;
1062: case ID:
1063: if (tsym && tsym->sclass == TYPEDEF
1064: && type == 0 && size == 0 && sign == 0) {
1065: use(tsym, src);
1066: ty = tsym->type;
1067: t = tt = ty->op;
1068: break;
1069: }
1070: /* fall through */
1071: default:
1072: p = 0;
1073: }
1074: if (p == 0)
1075: break;
1076: if (*p)
1077: error("invalid use of `%k'\n", tt);
1078: *p = tt;
1079: if (t == tt)
1080: t = gettok();
1081: }
1082: if (type == 0) {
1083: type = INT;
1084: ty = inttype;
1085: }
1086: if (size == SHORT && type != INT
1087: || size == LONG && type != INT && type != DOUBLE
1088: || sign && type != INT && type != CHAR)
1089: error("invalid type specification\n");
1090: if (type == CHAR && sign)
1091: ty = sign == UNSIGNED ? unsignedchar : signedchar;
1092: else if (size == SHORT)
1093: ty = sign == UNSIGNED ? unsignedshort : shorttype;
1094: else if (size == LONG && type == DOUBLE)
1095: ty = longdouble;
1096: else if (size == LONG)
1097: ty = sign == UNSIGNED ? unsignedlong : longtype;
1098: else if (sign == UNSIGNED && type == INT)
1099: ty = unsignedtype;
1100: if (cons == CONST)
1101: ty = qual(CONST, ty);
1102: if (vol == VOLATILE)
1103: ty = qual(VOLATILE, ty);
1104: return ty;
1105: }
1106:
1107: /* typename - type dclr */
1108: Type typename() {
1109: Type ty = type(0, (int *)0);
1110:
1111: if (t == '*' || t == '(' || t == '[') {
1112: ty = dclr(ty, (char **)0, (Symbol **)0);
1113: if (Aflag >= 1 && !hasproto(ty))
1114: warning("missing prototype\n");
1115: }
1116: return ty;
1117: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.