|
|
1.1 root 1: /*
2: * n0/gdecl.c
3: * Read in declarators and build up the DIM and INFO structures.
4: */
5:
6: #ifdef vax
7: #include "INC$LIB:cc0.h"
8: #else
9: #include "cc0.h"
10: #endif
11:
12: /*
13: * Read declarator.
14: * The arg "tdp" is the dimensions from a typedef.
15: * The storage class is passed since
16: * it determines the lexic level of the lookup.
17: */
18: gdecl(asp, adp, tdp, c, ls)
19: SYM **asp;
20: DIM **adp, *tdp;
21: int c, ls;
22: {
23: register SYM *sp;
24: DIM *dp;
25: int ll; /* Lexical level */
26: int aok; /* Args are OK flag */
27: sizeof_t bound; /* Array bound */
28:
29: aok = (llex==LL_EXT && (c==C_GDEF || c==C_GREF || c==C_SEX) && nargs==0);
30: while (s == CONST || s == VOLATILE) {
31: /* Ignore these for now. They should be treated as MUL */
32: /* They can appear before the type-name as well */
33: lex();
34: }
35: if (s == MUL) {
36: lex();
37: if (gdecl(asp, adp, NULL, c, ls) == 0)
38: return 0;
39: *adp = tackdim(*adp, D_PTR, (sizeof_t)0);
40: while (tdp != NULL) {
41: *adp = tackdim(*adp, tdp->d_type, tdp->d_bound);
42: tdp = tdp->d_dp;
43: }
44: return 1;
45: }
46: if (s == LPAREN) {
47: lex();
48: if (gdecl(asp, adp, NULL, c, ls) == 0)
49: return 0;
50: mustbe(RPAREN);
51: sp = *asp;
52: dp = *adp;
53: if (nargs != 0)
54: aok = 0;
55: } else if (s == ID) {
56: if (c==C_ARG || c==C_PAUTO || c==C_PREG)
57: ll = LL_ARG;
58: else if (c==C_GDEF || c==C_GREF)
59: ll = LL_EXT;
60: else
61: ll = llex;
62: sp = deflookup(ls, ll);
63: dp = NULL;
64: lex();
65: } else {
66: cerror("declarator syntax");
67: while (s!=EOF && s!=COMMA && s!=SEMI)
68: skip();
69: return 0;
70: }
71: again:
72: if (s == LPAREN) {
73: lex();
74: garglist(&aok, &dp);
75: mustbe(RPAREN);
76: goto again;
77: }
78: if (s == LBRACK) {
79: lex();
80: bound = 0;
81: if (s != RBRACK)
82: bound = getbound();
83: mustbe(RBRACK);
84: dp = tackdim(dp, D_ARRAY, bound);
85: goto again;
86: }
87: while (tdp != NULL) {
88: dp = tackdim(dp, tdp->d_type, tdp->d_bound);
89: tdp = tdp->d_dp;
90: }
91: *asp = sp;
92: *adp = dp;
93: return 1;
94: }
95:
96: /*
97: * This routine generates tags for tagless struct/union/enum
98: * declarations. This makes life easier for csd.
99: */
100: SYM *newtag(ll) int ll;
101: {
102: sprintf(id, ".%d", newlab());
103: setid(id);
104: return deflookup(SL_TAG, ll);
105: }
106:
107: /*
108: * This routine processes structure and union declarations.
109: * The type and INFO data gets passed back indirectly through the
110: * "call by reference" parameters.
111: * The storage class is passed so that local extern structure
112: * definitions get entered at the correct (global) lexical level.
113: */
114: gstruct(sc, at, aip)
115: int sc, *at;
116: INFO **aip;
117: {
118: int c, dt, i, j, mc, t, tc, w, rf, ls, ll, nbpstrg;
119: SYM *tsp, *msp, *mp;
120: DIM *dp, **mdp;
121: INFO *ip, *nip;
122: TOK *oidp;
123: unsigned long ofs, max, bitsize;
124:
125: ll = (sc == C_GREF) ? LL_EXT : llex;
126: ls = lsym;
127: if (notvariant(VSINU))
128: lsym += 1;
129: dt = T_STRUCT;
130: tc = C_STAG;
131: mc = C_MOS;
132: if (s == UNION) {
133: dt = T_UNION;
134: tc = C_UTAG;
135: mc = C_MOU;
136: }
137: tsp = NULL;
138: lex();
139: if (s == ID) {
140: tsp = reflookup(SL_TAG);
141: if (tsp == NULL)
142: tsp = deflookup(SL_TAG, ll);
143: oidp = idp; /* save idp, lex() may clobber it */
144: lex();
145: if (s != LBRACE) {
146: c = tsp->s_class;
147: if (c == C_NONE) {
148: *at = dt+1; /* Forward */
149: *aip = tsp;
150: return;
151: }
152: if (c==C_STAG || c==C_UTAG) {
153: if (c != tc)
154: tagmismatch(tsp);
155: *at = dt;
156: *aip = tsp->s_ip;
157: ++tsp->s_ip->i_refc;
158: return;
159: }
160: cerror("\"%s\" is not a tag", tsp->s_id);
161: *at = T_INT;
162: *aip = NULL;
163: return;
164: }
165: idp = oidp; /* restore idp for deflookup() */
166: tsp = deflookup(SL_TAG, ll);
167: } else
168: tsp = newtag(ll);
169: mustbe(LBRACE);
170: nip = (INFO *) new(sizeof(INFO));
171: nip->i_refc = 1;
172: nip->i_nsp = 0;
173: ofs = 0;
174: max = 0;
175: while (s!=EOF && s!=RBRACE) {
176: gcandt(&c, &t, &dp, &ip, &rf);
177: if (t == T_NONE) {
178: if (s == ID)
179: cerror("\"%s\" is not a typedef name", id);
180: else
181: cerror("missing type in structure body");
182: while (s!=EOF && s!=RBRACE && s!=SEMI)
183: lex();
184: if (s == SEMI)
185: lex();
186: continue;
187: }
188: if (rf != 0 || c != C_NONE)
189: cerror("class not allowed in structure body");
190: if (isvariant(VSINU)) {
191: /*
192: * Handle the "struct" in "union" rule.
193: * A series of unnamed structures within a union are united
194: * into a set of named/typed offsets within the union.
195: * Basically, we add the unique members of the
196: * new structure to the members of the current union.
197: * Not strictly part of C, and only works if all MOS in
198: * same level of symbol table.
199: */
200: if (dt==T_UNION && t==T_STRUCT && s==SEMI) {
201: notbook();
202: lex();
203: bitsize = (unsigned long)ip->i_size*NBPBYTE;
204: if (bitsize > max)
205: max = bitsize;
206: for (i=0; i<ip->i_nsp; ++i) {
207: mp = ip->i_sp[i];
208: j = nip->i_nsp;
209: while (--j >= 0)
210: if (nip->i_sp[j] == mp)
211: break;
212: if (j < 0) {
213: nip = newinfo(nip, mp);
214: if (tsp != NULL)
215: mp->s_flag |= S_TAG;
216: }
217: }
218: continue;
219: }
220: }
221: for (;;) {
222: if (s == COLON) {
223: lex();
224: newtree(sizeof(TREE));
225: ++ininit;
226: w = iconexpr();
227: --ininit;
228: if (w < 0)
229: cerror("bad filler field width");
230: ofs = fieldalign(t, NULL, ip, w, ofs) + w;
231: } else if (gdecl(&msp, &mdp, dp, mc, ls)) {
232: if (sc == C_GREF)
233: msp->s_level = LL_EXT;
234: w = 0;
235: if (s == COLON) {
236: lex();
237: newtree(sizeof(TREE));
238: ++ininit;
239: w = iconexpr();
240: --ininit;
241: if (w <= 0)
242: cerror("bad field width");
243: }
244: ofs = fieldalign(t, mdp, ip, w, ofs);
245: msp = declare(msp, mc, t, mdp, ip, rf, w, ofs);
246: nip = newinfo(nip, msp);
247: if (tsp != NULL)
248: msp->s_flag |= S_TAG;
249: if (w == 0)
250: ofs += (unsigned long)ssize(msp)*NBPBYTE;
251: else
252: ofs += w;
253: }
254: if (dt == T_UNION) {
255: if (ofs > max)
256: max = ofs;
257: ofs = 0;
258: }
259: if (s != COMMA)
260: break;
261: lex();
262: }
263: xdropinfo(t, ip);
264: mustbe(SEMI);
265: }
266: mustbe(RBRACE);
267: if (dt == T_STRUCT)
268: max = ofs;
269: nbpstrg = saligntype(nip) * NBPBYTE;
270: if (nbpstrg == 0)
271: nbpstrg = NBPBYTE;
272: max = (max + nbpstrg - 1) / nbpstrg;
273: max = max * nbpstrg / NBPBYTE;
274: if (max > MAXESIZE) {
275: cerror("size of %s too large",
276: (dt==T_STRUCT) ? "struct" : "union");
277: max = 0;
278: }
279: nip->i_size = max;
280: if (tsp != NULL)
281: tsp = declare(tsp, tc, 0, NULL, nip, 0);
282: *at = dt;
283: *aip = nip;
284: }
285:
286: /*
287: * Read an enumeration.
288: */
289: genum(sc, at, aip)
290: int sc, *at;
291: INFO **aip;
292: {
293: register SYM *sp, *tsp;
294: INFO *ip;
295: TOK *oidp;
296: int c, emv, emvmax, emvmin, ll;
297:
298: ll = (sc == C_GREF) ? LL_EXT : llex;
299: tsp = NULL;
300: lex();
301: if (s == ID) {
302: tsp = reflookup(SL_TAG);
303: oidp = idp; /* save idp, lex() may clobber it */
304: lex();
305: if (s != LBRACE) {
306: if (tsp == NULL)
307: tsp = deflookup(SL_TAG, ll);
308: c = tsp->s_class;
309: if (c == C_NONE) {
310: *at = T_FENUM;
311: *aip = tsp;
312: return;
313: }
314: if (c == C_ETAG) {
315: *at = T_ENUM;
316: *aip = tsp->s_ip;
317: ++tsp->s_ip->i_refc;
318: return;
319: }
320: cerror("\"%s\" is not an \"enum\" tag",
321: tsp->s_id);
322: *at = T_INT;
323: *aip = NULL;
324: return;
325: }
326: idp = oidp; /* restore idp for deflookup() */
327: tsp = deflookup(SL_TAG, ll);
328: } else
329: tsp = newtag(ll);
330: mustbe(LBRACE);
331: ip = (INFO *) new(sizeof(INFO));
332: ip->i_refc = 1;
333: ip->i_nsp = 0;
334: emvmax = emvmin = emv = 0;
335: for (;;) {
336: if (s==EOF || (s==RBRACE && ip->i_nsp == 0)) {
337: cerror("unexpected end of enumeration list");
338: break;
339: } else if (s==RBRACE) {
340: cwarn("trailing ',' in enumeration list");
341: break;
342: } else if (s != ID) {
343: cerror("error in enumeration list syntax");
344: skip();
345: continue;
346: }
347: sp = deflookup(SL_VAR, ll);
348: lex();
349: if (s == ASSIGN) {
350: lex();
351: newtree(sizeof(TREE));
352: ++ininit;
353: emv = iconexpr();
354: --ininit;
355: }
356: if (emv > emvmax)
357: emvmax = emv;
358: if (emv < emvmin)
359: emvmin = emv;
360: ip = newinfo(ip, sp);
361: sp = declare(sp, C_MOE, 0, NULL, NULL, 0, emv);
362: ++emv;
363: if (s == RBRACE)
364: break;
365: mustbe(COMMA);
366: }
367: if (s == RBRACE)
368: lex();
369: ip->i_type = (emvmax>MAXUCE || emvmin<0) ? T_INT : T_UCHAR;
370: if (tsp != NULL)
371: tsp = declare(tsp, C_ETAG, 0, NULL, ip, 0);
372: *at = T_ENUM;
373: *aip = ip;
374: }
375:
376: /*
377: * Read an old-style K&R function argument list.
378: * '*aokp' indicates whether the storage class of the parent declarator
379: * and the position of the parenthesized list is appropriate for the
380: * formal parameter list of an actual function definition.
381: * '*adp' is where the function prototype DIM should be stored.
382: */
383: garglist(aokp, adp) register int *aokp; register DIM **adp;
384: {
385: register SYM *ap;
386:
387: if (*aokp==1) {
388: nargs = 0;
389: if (s != RPAREN)
390: for (;;) {
391: if (s != ID) {
392: cerror("argument list has incorrect syntax");
393: break;
394: }
395: if (nargs >= NARGS)
396: cfatal("too many arguments");
397: ap = deflookup(SL_VAR, LL_ARG);
398: ap = declare(ap, C_ARG, T_INT,
399: NULL, NULL, 0);
400: args[nargs++] = ap;
401: lex();
402: if (s != COMMA)
403: break;
404: lex();
405: }
406: *aokp = 0;
407: }
408: *adp = tackdim(*adp, D_FUNC, (sizeof_t)0);
409: }
410:
411: /*
412: * Tack a DIM structure onto the end
413: * of the dimension list associated with "dp".
414: */
415: DIM *
416: tackdim(dp, t, b)
417: DIM *dp;
418: int t;
419: sizeof_t b;
420: {
421: register DIM *dp1, *dp2;
422:
423: dp1 = (struct dim *) new(sizeof(struct dim));
424: dp1->d_dp = NULL;
425: dp1->d_type = t;
426: dp1->d_bound = b;
427: if ((dp2 = dp) == NULL)
428: return dp1;
429: while (dp2->d_dp != NULL)
430: dp2 = dp2->d_dp;
431: dp2->d_dp = dp1;
432: return dp;
433: }
434:
435: /*
436: * Release a DIM chain.
437: */
438: dropdim(dp)
439: register DIM *dp;
440: {
441: if (dp != NULL) {
442: dropdim(dp->d_dp);
443: free((char *) dp);
444: }
445: }
446:
447: /*
448: * Duplicate a DIM chain.
449: */
450: DIM *
451: dupldim(dp)
452: register DIM *dp;
453: {
454: register DIM *np;
455:
456: if (dp == NULL)
457: return NULL;
458: np = (struct dim *) new(sizeof(struct dim));
459: np->d_dp = dupldim(dp->d_dp);
460: np->d_type = dp->d_type;
461: np->d_bound = dp->d_bound;
462: return np;
463: }
464:
465: /*
466: * Append a symbol to a struct/union/enum information array.
467: * Grow the array if necessary and possible.
468: */
469: INFO *
470: newinfo(ip, sp)
471: register INFO *ip;
472: SYM *sp;
473: {
474: register INFO *tip;
475: register int i;
476:
477: i = ip->i_nsp;
478: if ((i % 16) == 0) {
479: tip = ip;
480: ip = (INFO *) new(sizeof(INFO) + (i+16) * sizeof(SYM *));
481: ip->i_refc = tip->i_refc;
482: ip->i_data = tip->i_data;
483: ip->i_nsp = i;
484: while (--i >= 0)
485: ip->i_sp[i] = tip->i_sp[i];
486: free((char *) tip);
487: i = ip->i_nsp;
488: }
489: ip->i_sp[i] = sp;
490: ip->i_nsp += 1;
491: return ip;
492: }
493:
494: /*
495: * Read an array bound.
496: * An array bound is a constant expression.
497: * It may be inside a cast, so save and restore the tree allocate pointer.
498: * If signed, give an error if the bound is less than 0.
499: * Call the machine dependent size check routine for upper bound check.
500: */
501: sizeof_t getbound()
502: {
503: register TREE *tp;
504: extern TREE *expr();
505: register int t;
506: register long bound;
507: TREE *tmp;
508:
509: tmp = talloc();
510: tp = expr();
511: treset(tmp);
512: if (tp->t_op == ICON)
513: bound = tp->t_ival;
514: else if (tp->t_op == LCON)
515: bound = tp->t_lval;
516: else if (tp->t_op == ZCON)
517: bound = tp->t_zval;
518: else {
519: cerror("array bound must be a constant");
520: return 0;
521: }
522: t = tltype(tp);
523: if ((t==T_CHAR || t==T_SHORT || t==T_INT || t==T_LONG)
524: && bound < 0) {
525: cerror("array bound must be positive");
526: return 0;
527: }
528: return szcheck(bound, 1, "array bound");
529: }
530:
531: /*
532: * The SYM 'sp' has storage class C_STAG or C_UTAG.
533: * A new declaration has been encountered which is of the wrong class.
534: * Print a diagnostic giving the name of the tag and its previous class.
535: */
536: tagmismatch(sp)
537: register SYM *sp;
538: {
539: register char *p;
540:
541: p = (sp->s_class == C_UTAG) ? "union" : "structure";
542: cerror("\"%s\" is a %s tag", sp->s_id, p);
543: }
544:
545: /*
546: * Read a cast.
547: * Return a pointer to a CAST tree node,
548: * or NULL if not a legal cast.
549: */
550: TREE *
551: cast()
552: {
553: register TREE *tp;
554: DIM *dp;
555: INFO *ip;
556: DIM *cast1();
557: int rf;
558: int c, t;
559:
560: gcandt(&c, &t, &dp, &ip, &rf);
561: if (c==C_NONE && t==T_NONE && rf==0)
562: return NULL;
563: if (rf != 0 || c != C_NONE)
564: cerror("storage class not allowed in cast");
565: if (t == T_NONE) {
566: cerror("type required in cast");
567: t = T_INT;
568: }
569: dp = cast1(dp);
570: if (t==T_VOID && dp!=NULL && !isfunction(dp)) {
571: cerror("illegal use of void type in cast");
572: t = T_INT;
573: }
574: mustbe(RPAREN);
575: tp = talloc();
576: tp->t_op = CAST;
577: tp->t_type = t;
578: tp->t_dp = dp;
579: tp->t_ip = ip;
580: xdropinfo(t, ip);
581: return tp;
582: }
583:
584: /* this is the cast version of gdecl() */
585: DIM *
586: cast1(tdp)
587: DIM *tdp;
588: {
589: register DIM *dp;
590: register sizeof_t b;
591: DIM *cast2();
592:
593: while (s == CONST || s == VOLATILE) {
594: lex();
595: }
596: if (s == MUL) {
597: lex();
598: dp = cast2(cast1(NULL), D_PTR, (sizeof_t)0);
599: } else {
600: dp = NULL;
601: if (s == LPAREN) {
602: lex();
603: if (s != RPAREN) {
604: dp = cast1(NULL);
605: mustbe(RPAREN);
606: } else {
607: lex();
608: dp = cast2(dp, D_FUNC, (sizeof_t)0);
609: }
610: }
611: again:
612: if (s == LPAREN) {
613: DIM *tdp;
614: lex();
615: tdp = dp;
616: cproto(&tdp);
617: dp = tdp;
618: mustbe(RPAREN);
619: goto again;
620: }
621: if (s == LBRACK) {
622: lex();
623: b = 0;
624: if (s != RBRACK)
625: b = getbound();
626: mustbe(RBRACK);
627: dp = cast2(dp, D_ARRAY, b);
628: goto again;
629: }
630: }
631: while (tdp != NULL) {
632: dp = cast2(dp, tdp->d_type, tdp->d_bound);
633: tdp = tdp->d_dp;
634: }
635: return dp;
636: }
637:
638: /* this is the cast version of tackdim() */
639: DIM *
640: cast2(dp, t, b)
641: DIM *dp;
642: int t;
643: sizeof_t b;
644: {
645: register DIM *dp1, *dp2;
646:
647: dp1 = (struct dim *) talloc();
648: dp1->d_dp = NULL;
649: dp1->d_type = t;
650: dp1->d_bound = b;
651: if ((dp2 = dp) == NULL)
652: return dp1;
653: while (dp2->d_dp != NULL)
654: dp2 = dp2->d_dp;
655: dp2->d_dp = dp1;
656: return dp;
657: }
658:
659: cproto(adp) DIM **adp;
660: {
661: *adp = cast2(*adp, D_FUNC, (sizeof_t)0);
662: }
663:
664: /* end of n0/gdecl.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.