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