|
|
1.1 root 1: /*
2: * n0/expr.c
3: * C compiler.
4: * Expressions et al.
5: */
6:
7: #ifdef vax
8: #include "INC$LIB:cc0.h"
9: #else
10: #include "cc0.h"
11: #endif
12:
13: #define LOW 0
14: #define HIGH 0177
15: #define INARGS 0200
16:
17: #define bcvint(p) bconvert((p), T_INT, NULL, NULL, NULL)
18: #define isfloat(t) ((t)==T_FLOAT || (t)==T_DOUBLE)
19: #define isshift(op) ((op)==ASHL || (op)==ASHR || (op)==SHL || (op)==SHR)
20: #define issgnint(t) ((t)== T_CHAR || (t)== T_SHORT || (t)== T_INT || (t)== T_LONG)
21: #define isunsint(t) ((t)==T_UCHAR || (t)==T_USHORT || (t)==T_UINT || (t)==T_ULONG)
22:
23: static char tclash[] = "type clash";
24:
25: /*
26: * Read a tree.
27: * This is the top level routine that is called by the user.
28: * The mysterious call to "build" with opcode "NOP" is to get any function or
29: * array name conversions applied, even if the top of the tree is a term.
30: * Ditto for getting types converted to computables.
31: */
32: TREE *
33: expr()
34: {
35: if (notvariant(VCPP)) {
36: bput(LINE);
37: iput((ival_t) line);
38: }
39: return build(NOP, tree(LOW), NULL);
40: }
41:
42: /*
43: * Read in a tree.
44: * The "n" argument is a firewall precedence.
45: * You continue reading until the precedence of the operator
46: * in the input is less than the priority "n".
47: * The "INARGS" flag is or'ed into the priority to indicate
48: * that the expression is an argument list, and that "," is special.
49: * Passing it in this unconventional way lets you pass a single
50: * parameter to "tree".
51: */
52: TREE *
53: tree(n)
54: {
55: register TREE *lp, *rp;
56: register SYM *sp;
57: DIM *dp;
58: TREE *tp, *fp;
59: int c, d, op, p, isarray, isinargs;
60:
61: isinargs = 0;
62: if ((n&INARGS) != 0) {
63: ++isinargs;
64: n &= ~INARGS;
65: }
66: lp = term();
67: for (;;) {
68: switch (s) {
69:
70: case LPAREN:
71: lex();
72: rp = NULL;
73: if (s != RPAREN)
74: rp = tree(LOW|INARGS);
75: mustbe(RPAREN);
76: lp = build(CALL, lp, rp);
77: break;
78:
79: case LBRACK:
80: lex();
81: lp = build(ADD, lp, tree(LOW));
82: adjust(lp, lp->t_type, lp->t_dp, lp->t_ip);
83: lp = build(STAR, lp, NULL);
84: mustbe(RBRACK);
85: break;
86:
87: case DOT:
88: case ARROW:
89: lp = build((s==DOT?ADDR:NOP), lp, NULL);
90: if (lex() != ID) {
91: cerror("missing member");
92: break;
93: }
94: sp = moslookup(lp);
95: if (bitcompat(T_PTR, tltype(lp)) == 0)
96: cerror("left side of \"%s\" not usable",
97: s==DOT?".":"->");
98: if (sp==NULL || ((c=sp->s_class)!=C_MOS && c!=C_MOU)) {
99: cerror("member \"%s\" is not defined", id);
100: sp = fakedef(SL_MOS);
101: } else if (isvariant(VSMEMB))
102: csmemb(lp, sp);
103: lex();
104: tp = talloc();
105: tp->t_op = ADD;
106: tp->t_lp = lp;
107: tp->t_rp = bicon(sp->s_value);
108: lp = tp;
109: isarray = 0;
110: dp = sp->s_dp;
111: if (dp!=NULL && dp->d_type==D_ARRAY) {
112: ++isarray;
113: dp = tdalloc(dp->d_dp, D_MOSAR, dp->d_bound);
114: } else
115: dp = tdalloc(dp, D_PTR, (sizeof_t)0);
116: adjust(lp, sp->s_type, dp, sp->s_ip);
117: if (!isarray)
118: lp = build(STAR, lp, NULL);
119: if (sp->s_width != 0) {
120: fp = talloc();
121: fp->t_op = FIELD;
122: fp->t_type = lp->t_type;
123: fp->t_lp = lp;
124: fp->t_width = sp->s_width;
125: fp->t_base = sp->s_offset;
126: lp = fp;
127: }
128: break;
129:
130: case INCBEF:
131: case DECBEF:
132: op = s+INCAFT-INCBEF;
133: lex();
134: lp = build(op, lp, bicon((ival_t)1));
135: break;
136:
137: default:
138: if ((s==COMMA && ininit!=0 && isinargs==0)
139: || (s==COLON))
140: goto out;
141: if (s<MIOBASE || s>=MDOBASE)
142: goto out;
143: d = opdope[s-MIOBASE];
144: if ((p=(d&PRIO)) == 0)
145: goto out;
146: if (p<n || ((d&RAS)==0 && p==n))
147: goto out;
148: if ((op = s) == QUEST) {
149: lex();
150: rp = tree(LOW);
151: mustbe(COLON);
152: rp = build(COLON, rp, tree(--p));
153: lp = build(QUEST, lp, rp);
154: break;
155: }
156: if (op==COMMA && isinargs!=0)
157: op = ARGLST;
158: lex();
159: lp = build(op, lp, tree(p));
160: }
161: }
162: out:
163: return lp;
164: }
165:
166: /*
167: * Check that a structure member is
168: * indeed a member of the left hand structure.
169: * If the member is untagged, don't object to any clash.
170: * The structure declaration reader sets the S_TAG bit
171: * in the flags word of all tagged structures.
172: */
173: csmemb(lp, sp)
174: TREE *lp;
175: SYM *sp;
176: {
177: register INFO *ip;
178: register SYM *tsp;
179: register int type;
180: char *msg;
181: int i;
182:
183: type = lp->t_type;
184: if (lp->t_dp==NULL || lp->t_dp->d_type!=D_PTR
185: || type<T_STRUCT || type>T_FUNION) {
186: cstrict("potentially nonportable structure access");
187: return;
188: }
189: if ((type==T_STRUCT || type==T_UNION) && (sp->s_flag&S_TAG)!=0) {
190: ip = lp->t_ip;
191: if (ip != NULL) {
192: for (i=0; i<ip->i_nsp && ip->i_sp[i]!=sp; ++i)
193: ;
194: if (i >= ip->i_nsp) {
195: tsp = taglookup(ip);
196: if (tsp != NULL) {
197: msg = (tsp->s_class == C_UTAG) ? "union" : "structure";
198: if (tsp->s_id[0] != '.')
199: cstrict("%s \"%s\" does not contain member \"%s\"",
200: msg, tsp->s_id, sp->s_id);
201: else
202: cstrict("%s does not contain member \"%s\"",
203: msg, sp->s_id);
204: }
205: }
206: }
207: }
208: }
209:
210: /*
211: * Read a term.
212: * Handle all of the leaf nodes and the unary operations here.
213: */
214: TREE *
215: term()
216: {
217: register TREE *tp;
218: register SYM *sp;
219: register int op;
220: TREE *cp;
221: DIM *dp;
222: int tt, lt, n;
223:
224: switch (op = s) {
225:
226: case ICON:
227: tp = bicon(ival);
228: tp->t_type = tval;
229: lex();
230: break;
231:
232: case LCON:
233: tp = talloc();
234: tp->t_op = LCON;
235: tp->t_type = tval;
236: tp->t_lval = lval;
237: lex();
238: break;
239:
240: case DCON:
241: tp = talloc();
242: tp->t_op = DCON;
243: tp->t_type = tval;
244: memcpy((char *)tp->t_dval, (char *)dval, sizeof(dval_t));
245: lex();
246: break;
247:
248: case STRING:
249: tp = bstring();
250: break;
251:
252: case ID:
253: if ((sp=reflookup(SL_VAR)) == NULL) {
254: /*
255: * An undefined name followed by a "(" is declared
256: * to be a function that returns an integer.
257: * So says the manual.
258: */
259: TOK *tp;
260: tp = idp;
261: if (spnextis('(')) {
262: setid(tp->t_id);
263: sp = deflookup(SL_VAR, 0);
264: dp = tackdim(NULL, D_FUNC, 0);
265: sp = declare(sp, C_CXT, T_INT, dp, NULL, 0);
266: } else
267: setid(tp->t_id);
268: if (sp == NULL) {
269: cerror("identifier \"%s\" is not defined", id);
270: sp = fakedef(SL_VAR);
271: }
272: }
273: tp = bid(sp);
274: lex();
275: break;
276:
277: case LPAREN:
278: lex();
279: if ((cp=cast()) != NULL) {
280: if (cp->t_type==T_FLOAT && cp->t_dp==NULL)
281: cp->t_type = T_DOUBLE;
282: cp->t_lp = build(NOP, tree(HIGH), NULL);
283: tt = tltype(cp);
284: lt = tltype(cp->t_lp);
285: if (tt == T_STRUCT)
286: cerror("cannot cast to structure or union");
287: if (lt == T_STRUCT)
288: cerror("cannot cast structure or union");
289: if (tt == T_PTR && isfloat(lt))
290: cerror("cannot cast double to pointer");
291: if (isfloat(tt) && lt == T_PTR)
292: cerror("cannot cast pointer to double");
293: if (bitcompat(tt, lt)) {
294: tp = cp->t_lp;
295: adjust(tp, cp->t_type, cp->t_dp, cp->t_ip);
296: if (tp->t_op == CONVERT && tp->t_rp == NULL)
297: tp->t_op = CAST;
298: } else
299: tp = cp;
300: break;
301: }
302: n = ininit;
303: ininit = 0;
304: tp = tree(LOW);
305: ininit = n;
306: mustbe(RPAREN);
307: break;
308:
309: case SIZEOF:
310: lex();
311: if (s == LPAREN) {
312: lex();
313: if ((tp=cast()) == NULL) {
314: tp = tree(LOW);
315: mustbe(RPAREN);
316: }
317: } else
318: tp = tree(HIGH);
319: tp = build(SIZEOF, tp, NULL);
320: break;
321:
322: case NOT:
323: lex();
324: tp = build(EQ, tree(HIGH), bicon((ival_t)0));
325: break;
326:
327: case SUB:
328: op = NEG;
329: goto unary;
330: case ADD: /* Unary plus == no rearrangement FIX.ME */
331: lex();
332: tp = tree(HIGH); /* ignored for present */
333: break;
334: op = POS;
335: goto unary;
336: case MUL:
337: op = STAR;
338: goto unary;
339: case AND:
340: op = ADDR;
341: goto unary;
342: case COM:
343: unary:
344: lex();
345: tp = build(op, tree(HIGH), NULL);
346: break;
347:
348: case INCBEF:
349: case DECBEF:
350: lex();
351: tp = build(op, tree(HIGH), bicon((ival_t)1));
352: break;
353:
354: default:
355: cerror("error in expression syntax");
356: while (s!=EOF && s!=SEMI && s!=LBRACE && s!=RBRACE)
357: skip();
358: return bicon((ival_t)0);
359: }
360: return tp;
361: }
362:
363: /*
364: * Given an operator "op" and left and right subtrees "lp" and "rp",
365: * build a tree node, folding any constant expressions
366: * that can be folded, supplying any required type conversions.
367: * All of the conversions that are possible are added;
368: * the routine "transform" may remove some of them.
369: */
370: TREE *
371: build(op, lp, rp) int op; TREE *lp; TREE *rp;
372: {
373: TREE *tp, *gtp, gt;
374: DIM *dp;
375: int rt, lt, d, cv;
376: sizeof_t ll, lr;
377:
378: if (op == SIZEOF)
379: return bzcon(tsize(lp));
380: rt = T_NONE;
381: if (rp != NULL) {
382: chmos(rp);
383: rp = chfun(charray(rp));
384: rt = tltype(rp);
385: }
386: chmos(lp);
387: lp = charray(lp);
388: if (op!=ADDR && op!=CALL)
389: lp = chfun(lp);
390: lt = tltype(lp);
391: if (op == NOP)
392: goto conversion;
393: /*
394: * Make sure that the operands are
395: * suitable as operands of the specified operation.
396: * Look mainly at the type, although some consideration
397: * is made of storage class.
398: */
399: if (lt==T_VOID || rt==T_VOID) {
400: if ((op!=COMMA && op!=QUEST && op!=COLON)
401: || (op==COLON && lt!=rt)
402: || (op==QUEST && lt==T_VOID)) {
403: cerror("illegal operation on \"void\" type");
404: lt = T_INT;
405: rt = T_INT;
406: }
407: }
408: if (op==ADDR && lp->t_op==REG)
409: cerror("cannot apply unary '&' to a register variable");
410: if (op==ADDR && lp->t_op==FIELD)
411: cerror("cannot apply unary '&' to a bit field");
412: if (op==ADDR && lp->t_op==GID && lp->t_seg==SALIEN)
413: cerror("cannot apply unary '&' to an alien function");
414: d = opdope[op-MIOBASE];
415: if ((d&RLVL) != 0
416: && (lp->t_op<=DCON
417: || (lp->t_op>=MIOBASE && lp->t_op!=STAR && lp->t_op!=FIELD
418: && (lp->t_op!=CALL || lp->t_type!=T_STRUCT || lp->t_dp!=NULL)
419: )))
420: cerror("lvalue required");
421: if ((d&NFLT)!=0 && (isfloat(lt) || isfloat(rt)))
422: cerror("illegal use of floating point");
423: if (((d&NPTL)!=0 && lt==T_PTR) || ((d&NPTR)!=0 && rt==T_PTR))
424: cerror("illegal use of a pointer");
425: if (((d&NSTL)!=0 && lt==T_STRUCT) || ((d&NSTR)!=0 && rt==T_STRUCT))
426: cerror("illegal use of a structure or union");
427: if ((d&RTOL) != 0)
428: truth(lp);
429: if ((d&RTOR) != 0)
430: truth(rp);
431: /*
432: * The operation may just fold away to nothing.
433: * If so, return a pointer to the new, constant tree node.
434: */
435: if ((tp=fold0(op, lp, rp)) != NULL)
436: return tp;
437: /*
438: * Insert conversion nodes.
439: */
440: conversion:
441: gt.t_op = CONVERT;
442: gt.t_dp = NULL;
443: gt.t_ip = NULL;
444: switch (op) {
445:
446: case QUEST:
447: if (rp->t_op != COLON)
448: cerror("mismatched conditional");
449: /* Make sure the condition type 'lt' is computational. */
450: gt.t_type = (cvdope[13 * (lt - T_CHAR) + lt - T_CHAR] & GOAL);
451: gt.t_dp = lp->t_dp;
452: gt.t_ip = lp->t_ip;
453: if (bitcompat(tltype(>), lt) == 0)
454: lp = bcvt(lp, >);
455: /* then fall through... */
456:
457: case COMMA:
458: case ARGLST:
459: gt.t_type = rp->t_type;
460: gt.t_dp = rp->t_dp;
461: gt.t_ip = rp->t_ip;
462: break;
463:
464: case ANDAND:
465: case OROR:
466: case NOT:
467: gt.t_type = T_INT;
468: break;
469:
470: case CALL:
471: if ((dp = lp->t_dp)!=NULL && dp->d_type==D_FUNC)
472: gt.t_dp = dp->d_dp;
473: else if ((dp = lp->t_dp)!=NULL
474: && dp->d_type==D_PTR
475: && dp->d_dp->d_type==D_FUNC) {
476: cwarn("implicit '*' added to function call");
477: lp = build(STAR, lp, NULL);
478: gt.t_dp = dp->d_dp->d_dp;
479: } else
480: cerror("call of non function");
481: if (rp != NULL && rp->t_op != ARGLST) {
482: rp = build(NOP, rp, NULL);
483: rt = tltype(rp);
484: }
485: gt.t_type = lp->t_type;
486: gt.t_ip = lp->t_ip;
487: break;
488:
489: case STAR:
490: if ((dp = lp->t_dp)!=NULL && dp->d_type==D_PTR)
491: gt.t_dp = dp->d_dp;
492: else
493: cerror("indirection through non pointer");
494: gt.t_type = lp->t_type;
495: gt.t_ip = lp->t_ip;
496: break;
497:
498: case ADDR:
499: gt.t_type = lp->t_type;
500: gt.t_dp = tdalloc(lp->t_dp, D_PTR, (sizeof_t)0);
501: gt.t_ip = lp->t_ip;
502: break;
503:
504: default:
505: if (rt == T_NONE)
506: rt = lt;
507: if (isshift(op)) {
508: /*
509: * Shift ops: convert right op to T_INT,
510: * read dope table accordingly.
511: */
512: if (bitcompat(T_INT, rt) == 0)
513: rp = bcvint(rp);
514: rt = T_INT;
515: }
516: cv = cvdope[13*(lt-T_CHAR) + rt - T_CHAR];
517: if (noconvert(op, lt, rt))
518: cv &= ~(CVL|CVR|CVRA|CARA);
519: else if (isshift(op))
520: cv &= ~(CVR|CVRA);
521: gt.t_type = cv&GOAL;
522: gt.t_rp = NULL;
523: if ((cv&(GTL|GTR)) != 0) {
524: gtp = ((cv>L)!=0) ? lp : rp;
525: gt.t_type = gtp->t_type;
526: gt.t_dp = gtp->t_dp;
527: gt.t_ip = gtp->t_ip;
528: if ((cv&(CVL|CVR|CVRA)) != 0)
529: gt.t_rp = bzcon(psize(gtp));
530: }
531: if (gt.t_type == T_NONE && op!=NOP && lt!=T_VOID)
532: cerror(tclash);
533: if ((d&ASGN) != 0) {
534: gt.t_type = lp->t_type;
535: gt.t_dp = lp->t_dp;
536: gt.t_ip = lp->t_ip;
537: if (gt.t_dp == NULL) {
538: if (gt.t_type==T_CHAR
539: || gt.t_type==T_UCHAR
540: || gt.t_type==T_SHORT
541: || gt.t_type==T_ENUM
542: || gt.t_type==T_FENUM)
543: gt.t_type = T_INT;
544: if (gt.t_type == T_USHORT)
545: gt.t_type = T_UINT;
546: if (gt.t_type == T_FLOAT)
547: gt.t_type = T_DOUBLE;
548: }
549: /*
550: * The following ADIV and AREM type conversion code is somewhat bogus.
551: * The basic problem is that C requires "a op= b;" to give the same
552: * result as "a = a op b;".
553: * The code below makes sure that an unsigned right op remains unsigned,
554: * so the code tables can generate an unsigned op rather than a signed op.
555: * Actually, the problem is more general; "i *= 1.5;" should have the same
556: * effect as "i = (double)i * 1.5;" but it currently does "i *= (int) 1.5;".
557: * This code the most obvious inconsistencies, though.
558: */
559: if ((cv&CVRA) != 0) {
560: if ((op == ADIV || op == AREM)
561: && issgnint(gt.t_type) && isunsint(rt)) {
562: gt.t_type = sgn2uns(gt.t_type);
563: rp = bcvt(rp, >);
564: gt.t_type = uns2sgn(gt.t_type);
565: } else
566: rp = bcvt(rp, >);
567: } else if ((cv&CARA) != 0) {
568: gt.t_op = CAST;
569: gt.t_rp = NULL;
570: rp = bcvt(rp, >);
571: }
572: } else {
573: if (op>=INCBEF && op<=DECAFT)
574: cv &= ~CVL;
575: if (op == COLON && lt != rt) {
576: if (lt == T_PTR) {
577: if (iszero(rp)) {
578: gt.t_op = CAST;
579: gt.t_rp = NULL;
580: } else
581: cerror(tclash);
582: } else if (rt == T_PTR) {
583: if (iszero(lp)) {
584: gt.t_op = CAST;
585: gt.t_rp = NULL;
586: } else
587: cerror(tclash);
588: }
589: } else if (op == COLON && lt==T_VOID && rt==T_VOID)
590: gt.t_type = T_VOID;
591: if ((cv&CVL) != 0)
592: lp = bcvt(lp, >);
593: if (op==SHL || op==SHR) {
594: gt.t_type = lp->t_type;
595: gt.t_dp = lp->t_dp;
596: gt.t_ip = lp->t_ip;
597: } else if (rp!=NULL && (cv&CVR)!=0)
598: rp = bcvt(rp, >);
599: if ((cv&UREL)!=0 && (op>=GT && op<=LT))
600: op += UGT-GT;
601: if (op>=EQ && op<=ULT) {
602: gt.t_type = T_INT;
603: gt.t_dp = gt.t_ip = NULL;
604: }
605: }
606: }
607: if (op==NOP)
608: return lp;
609: tp = talloc();
610: tp->t_op = op;
611: tp->t_type = gt.t_type;
612: tp->t_dp = gt.t_dp;
613: tp->t_ip = gt.t_ip;
614: tp->t_lp = lp;
615: tp->t_rp = rp;
616: if (lt==T_PTR && rt==T_PTR) {
617: if (op == ADD)
618: cerror("cannot add pointers");
619: if (op == SUB) {
620: if ((ll=psize(lp)) != (lr=psize(rp)))
621: cerror("illegal subtraction of pointers");
622: tp = bconvert(tp, T_INT, NULL, NULL, bzcon(ll));
623: }
624: }
625: if (op==ASSIGN && lt==T_STRUCT && rt==T_STRUCT) {
626: notbook();
627: if ((ll=tsize(lp)) != (lr=tsize(rp)))
628: cerror("illegal structure assignment");
629: }
630: if (isvariant(VSPVAL) && lt != rt
631: && ((lt==T_PTR && !iszero(rp)) || (rt==T_PTR && !iszero(lp)))) {
632: if (op == ASSIGN)
633: cstrict("integer pointer pun");
634: else if (op >= EQ && op <= ULT)
635: cstrict("integer pointer comparison");
636: }
637: return tp;
638: }
639:
640: /*
641: * If the first entry in the dimensions of tree "tp" is a
642: * MOS array, stomp it into the pointer it truly is.
643: */
644: chmos(tp)
645: TREE *tp;
646: {
647: register struct dim *dp;
648:
649: if ((dp = tp->t_dp)!=NULL && dp->d_type==D_MOSAR) {
650: dp->d_type = D_PTR;
651: dp->d_bound = 0;
652: }
653: }
654:
655: /*
656: * Read constant expression.
657: * Call the standard expression reader, and make sure that
658: * the folder has squashed it down to nothing.
659: * Return the value.
660: */
661: ival_t
662: iconexpr()
663: {
664: register TREE *tp;
665:
666: tp = expr();
667: while (tp->t_op == CAST || tp->t_op == CONVERT)
668: tp = tp->t_lp;
669: if (tp->t_op == ICON)
670: return tp->t_ival;
671: if (tp->t_op == LCON && (ival_t)tp->t_lval == tp->t_lval)
672: return (ival_t)tp->t_lval;
673: if (tp->t_op == ZCON && (ival_t)tp->t_zval == tp->t_zval)
674: return (ival_t)tp->t_zval;
675: cerror("int constant expression required");
676: return (ival_t)0;
677: }
678:
679: /*
680: * Look for a constant zero of integral type.
681: */
682: iszero(tp)
683: register TREE *tp;
684: {
685: register int op;
686:
687: if (tp != NULL) {
688: while ((op = tp->t_op) == CONVERT || op == CAST)
689: tp = tp->t_lp;
690: if (op == ICON && tp->t_ival == 0)
691: return 1;
692: if (op == LCON && tp->t_lval == 0L)
693: return 1;
694: }
695: return 0;
696: }
697:
698: /*
699: * Build a conversion node.
700: * Used by build and stat when bcvt is unsuitable.
701: */
702: TREE *
703: bconvert(lp, gt, gdp, gip, rp)
704: TREE *lp, *rp;
705: DIM *gdp;
706: INFO *gip;
707: {
708: TREE t;
709:
710: t.t_op = CONVERT;
711: t.t_type = gt;
712: t.t_dp = gdp;
713: t.t_ip = gip;
714: t.t_rp = rp;
715: return bcvt(lp, &t);
716: }
717:
718: /*
719: * Build a conversion or cast node.
720: */
721: TREE *
722: bcvt(lp, gtp)
723: TREE *lp, *gtp;
724: {
725: register TREE *tp;
726:
727: tp = lp;
728: tp = talloc();
729: tp->t_op = gtp->t_op;
730: tp->t_type = gtp->t_type;
731: tp->t_dp = gtp->t_dp;
732: tp->t_ip = gtp->t_ip;
733: tp->t_lp = lp;
734: tp->t_rp = gtp->t_rp;
735: return tp;
736: }
737:
738: /*
739: * Given a pointer to its symbol table node,
740: * return a pointer to the tree node for an identifier.
741: * Enumeration tags get changed into integer constants here.
742: */
743: TREE *
744: bid(sp)
745: register SYM *sp;
746: {
747: register TREE *tp;
748:
749: sp->s_flag |= S_USED;
750: if (sp->s_class == C_MOE)
751: return bicon(sp->s_value);
752: tp = talloc();
753: switch (sp->s_class) {
754:
755: case C_AUTO:
756: tp->t_op = AID;
757: tp->t_offs = sp->s_value;
758: break;
759:
760: case C_PAUTO:
761: tp->t_op = PID;
762: tp->t_offs = sp->s_value;
763: break;
764:
765: case C_SIN:
766: tp->t_op = LID;
767: tp->t_seg = sp->s_seg;
768: tp->t_label = sp->s_value;
769: break;
770:
771: case C_REG:
772: tp->t_op = REG;
773: tp->t_reg = sp->s_value;
774: break;
775:
776: case C_GDEF:
777: case C_GREF:
778: case C_CXT:
779: case C_SEX:
780: tp->t_op = GID;
781: tp->t_seg = sp->s_seg;
782: tp->t_sp = sp;
783: break;
784:
785: default:
786: cerror("identifier \"%s\" not usable", sp->s_id);
787: tp->t_op = ICON;
788: tp->t_type = T_INT;
789: return tp;
790: }
791: tp->t_type = sp->s_type;
792: tp->t_dp = sp->s_dp;
793: tp->t_ip = sp->s_ip;
794: return tp;
795: }
796:
797: /*
798: * Build ICON tree node.
799: */
800: TREE *
801: bicon(n) ival_t n;
802: {
803: register TREE *tp;
804:
805: tp = talloc();
806: tp->t_op = ICON;
807: tp->t_type = T_INT;
808: tp->t_ival = n;
809: return tp;
810: }
811:
812: TREE *
813: bzcon(n)
814: sizeof_t n;
815: {
816: register TREE *tp;
817:
818: tp = talloc();
819: tp->t_op = ZCON;
820: tp->t_type = T_UINT;
821: tp->t_zval = n;
822: return tp;
823: }
824:
825: /*
826: * Read in a string and hide it in the string section.
827: * Return a pointer to a local identifier node;
828: * the local identifier is planted at the start of the string.
829: * The type of the node is set to array of char.
830: */
831: static
832: TREE *
833: bstring()
834: {
835: register TREE *tp;
836: register int c, nbb, nbs;
837: int old, lab, adj;
838: char bb[11];
839:
840: old = newseg(SSTRN);
841: lab = here();
842: nbb = nbs = adj = 0;
843: again:
844: instring = '"';
845: while ((c=getmap('\"')) >= 0) {
846: ++nbs;
847: if (nbb >= 10) { /* Leave space for NUL */
848: bsflush(bb, nbb);
849: nbb = 0;
850: }
851: bb[nbb++] = c;
852: }
853: instring = 0;
854: if (lex() == STRING) { /* e.g. "Hello " "world" */
855: ++adj;
856: goto again;
857: }
858: bb[nbb++] = 0;
859: bsflush(bb, nbb);
860: if (adj)
861: notbook();
862: newseg(old);
863: tp = talloc();
864: tp->t_op = LID;
865: tp->t_type = T_CHAR;
866: tp->t_dp = tdalloc(NULL, D_ARRAY, (sizeof_t)nbs+1);
867: tp->t_label = lab;
868: tp->t_seg = SSTRN;
869: return tp;
870: }
871:
872: /*
873: * Dump out the string buffer.
874: */
875: bsflush(bb, nbb)
876: register unsigned char *bb;
877: register int nbb;
878: {
879: bput(IBLOCK);
880: bput(nbb);
881: while (nbb--)
882: bput(*bb++);
883: }
884:
885: /*
886: * Make all the types and dims in a tree agree with the viewpoint at the top.
887: * This is used by casts and the code that builds up structure access trees.
888: */
889: adjust(tp, t, dp, ip)
890: register TREE *tp;
891: register DIM *dp;
892: INFO *ip;
893: {
894: register int op;
895:
896: again:
897: tp->t_type = t;
898: tp->t_dp = dp;
899: tp->t_ip = ip;
900: if ((op = tp->t_op) == ADDR) {
901: if (dp==NULL || (dp->d_type!=D_PTR && dp->d_type!=D_MOSAR))
902: return;
903: dp = dp->d_dp;
904: tp = tp->t_lp;
905: goto again;
906: }
907: if (op == STAR) {
908: dp = tdalloc(dp, D_PTR, (sizeof_t)0);
909: tp = tp->t_lp;
910: goto again;
911: }
912: if (dp!=NULL && dp->d_type==D_MOSAR)
913: dp = tdalloc(dp->d_dp, D_PTR, (sizeof_t)0);
914: if (op==CAST && bitcompat(tltype(tp), tltype(tp->t_lp))) {
915: tp = tp->t_lp;
916: goto again;
917: }
918: }
919:
920: /*
921: * If the tree "tp" is a pointer,
922: * return the size of the item to which the pointer points;
923: * if it is not a pointer, return 1.
924: */
925: sizeof_t psize(tp)
926: register TREE *tp;
927: {
928: register DIM *dp;
929: register sizeof_t n;
930:
931: dp = tp->t_dp;
932: if (dp==NULL || dp->d_type!=D_PTR)
933: return 1;
934: tp->t_dp = dp->d_dp;
935: n = tsize(tp);
936: tp->t_dp = dp;
937: return n;
938: }
939:
940: /*
941: * Check if a tree has type "function returning ...".
942: * If it does, modify the tree to add the free "address of".
943: */
944: TREE *
945: chfun(tp)
946: register TREE *tp;
947: {
948: register DIM *dp;
949:
950: dp = tp->t_dp;
951: if (dp!=NULL && dp->d_type==D_FUNC) {
952: tp = build(ADDR, tp, NULL);
953: adjust(tp, tp->t_type, tp->t_dp, tp->t_ip);
954: }
955: return tp;
956: }
957:
958: /*
959: * Check for arrays.
960: * Add the free '&' operation.
961: * We build the node ourselves (rather than calling build)
962: * to avoid a recursive call to this routine on
963: * a multidimensional structure.
964: */
965: TREE *
966: charray(tp)
967: register TREE *tp;
968: {
969: register TREE *ap;
970: register DIM *dp;
971:
972: dp = tp->t_dp;
973: if (dp!=NULL && dp->d_type==D_ARRAY) {
974: ap = talloc();
975: ap->t_op = ADDR;
976: ap->t_type = tp->t_type;
977: ap->t_dp = tdalloc(dp->d_dp, D_PTR, (sizeof_t)0);
978: ap->t_ip = tp->t_ip;
979: ap->t_lp = tp;
980: tp = ap;
981: adjust(tp, tp->t_type, tp->t_dp, tp->t_ip);
982: }
983: return tp;
984: }
985:
986: /*
987: * Given a tree node, get a type for the tree that is
988: * usable for indexing into the type conversion tables.
989: * All non-scalars are pointers.
990: * All structures and unions are structures.
991: * All enumerations are set right.
992: */
993: tltype(tp)
994: register TREE *tp;
995: {
996: register int type;
997:
998: if (tp->t_dp != NULL)
999: return T_PTR;
1000: if ((type=tp->t_type) == T_FENUM)
1001: return T_INT;
1002: if (type == T_ENUM)
1003: return tp->t_ip->i_type;
1004: if (type > T_VOID)
1005: return T_STRUCT;
1006: return type;
1007: }
1008:
1009: /*
1010: * Check if two linear types are "bit compatable".
1011: */
1012: bitcompat(t1, t2)
1013: {
1014: return noconvert(CAST, t1, t2);
1015: }
1016:
1017: /*
1018: * Allocate a new dim structure in the tree area.
1019: * Used to create pointers in the tree.
1020: */
1021: DIM *
1022: tdalloc(p, t, b)
1023: DIM *p;
1024: int t;
1025: sizeof_t b;
1026: {
1027: register DIM *dp;
1028:
1029: dp = (struct dim *) talloc();
1030: dp->d_dp = p;
1031: dp->d_type = t;
1032: dp->d_bound = b;
1033: return dp;
1034: }
1035:
1036: /*
1037: * Output a tree.
1038: */
1039: tput(why, lab, tp)
1040: register why;
1041: register TREE *tp;
1042: {
1043: tp = transform(tp, why, -1);
1044: bput(why);
1045: if (why==TEXPR || why==FEXPR)
1046: iput((ival_t) lab);
1047: tput1(tp);
1048: }
1049:
1050: /*
1051: * Output a tree, part II.
1052: */
1053: tput1(tp)
1054: register TREE *tp;
1055: {
1056: register int op;
1057:
1058: if (tp == NULL) {
1059: iput((ival_t) NIL);
1060: return;
1061: }
1062: op = tp->t_op;
1063: iput((ival_t) op);
1064: bput(tp->t_type);
1065: if (tp->t_type == BLK)
1066: iput((ival_t)tp->t_ip->i_size);
1067: switch (op) {
1068:
1069: case ICON:
1070: iput((ival_t) tp->t_ival);
1071: break;
1072:
1073: case LCON:
1074: lput(tp->t_lval);
1075: break;
1076:
1077: case ZCON:
1078: zput(tp->t_zval);
1079: break;
1080:
1081: case DCON:
1082: dput(tp->t_dval); /* An array */
1083: break;
1084:
1085: case AID:
1086: case PID:
1087: case LID:
1088: case GID:
1089: zput(tp->t_offs);
1090: if (op==LID || op==GID) {
1091: bput(tp->t_seg);
1092: if (op == LID)
1093: iput((ival_t) tp->t_label);
1094: else
1095: nput(tp->t_sp->s_id);
1096: }
1097: break;
1098:
1099: case REG:
1100: iput((ival_t) tp->t_reg);
1101: break;
1102:
1103: case FIELD:
1104: bput(tp->t_width);
1105: bput(tp->t_base);
1106: tput1(tp->t_lp);
1107: break;
1108:
1109: default:
1110: tput1(tp->t_lp);
1111: tput1(tp->t_rp);
1112: }
1113: }
1114:
1115: /* end of n0/expr.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.