|
|
1.1 root 1: /*
2: * C compiler.
3: * Statement compilation.
4: * The routines in this file compile C statements.
5: * This file also contains a number of small routines that are
6: * only used by the statement compilation code.
7: * This is the new VAX/VMS base version.
8: */
9: #ifdef vax
10: #include "INC$LIB:cc0.h"
11: #else
12: #include "cc0.h"
13: #endif
14:
15: /*
16: * Compile one statement.
17: * On entry, 's' contains the first symbol of the new statement.
18: * On exit, 's' contains the first token beyond the end of the statement.
19: */
20: statement()
21: {
22: register TREE *tp;
23: register int lab1, lab2;
24: TREE *lp, *rp;
25: TREE *itree, *ctree, *stree;
26: SBLOCK *ssbp;
27: int i, sclab, sblab, tt;
28: ival_t v;
29:
30: loop:
31: dbstat(s, line);
32: switch (s) {
33:
34: case EOF:
35: cerror("unexpected end of file");
36: break;
37:
38: case SEMI:
39: lex();
40: break;
41:
42: case LBRACE:
43: lex();
44: savelocals();
45: ++llex;
46: locals();
47: putautos();
48: while (s!=EOF && s!=RBRACE)
49: statement();
50: mustbe(RBRACE);
51: --llex;
52: downlex();
53: dbstat(RBRACE, line);
54: restlocals();
55: break;
56:
57: case BREAK:
58: lex();
59: if (cblab == 0)
60: cerror("break not in a loop");
61: jump(cblab);
62: mustbe(SEMI);
63: break;
64:
65: case CONTINUE:
66: lex();
67: if (cclab == 0)
68: cerror("continue not in a loop");
69: jump(cclab);
70: mustbe(SEMI);
71: break;
72:
73: case CASE:
74: lex();
75: newtree(sizeof(TREE));
76: ++incase;
77: v = iconexpr();
78: --incase;
79: mustbe(COLON);
80: if (sbp == NULL)
81: cerror("case not in a switch");
82: else
83: newcase(v);
84: goto loop;
85:
86: case DEFAULT:
87: lex();
88: mustbe(COLON);
89: if (sbp == NULL)
90: cerror("default label not in a switch");
91: else {
92: if (sbp->sb_dlab != 0)
93: cerror("only one default label allowed");
94: sbp->sb_dlab = here();
95: }
96: goto loop;
97:
98: case GOTO:
99: lex();
100: if (s != ID) {
101: cerror("missing label name in goto");
102: skip();
103: } else {
104: dogoto();
105: lex();
106: mustbe(SEMI);
107: }
108: break;
109:
110: case IF:
111: lex();
112: tp = pexpr();
113: truth(tp);
114: tput(FEXPR, lab1=newlab(), tp);
115: statement();
116: if (s == ELSE) {
117: lab2 = newlab();
118: jump(lab2);
119: label(lab1);
120: lex();
121: statement();
122: label(lab2);
123: break;
124: }
125: label(lab1);
126: break;
127:
128: case DO:
129: sblab = cblab;
130: sclab = cclab;
131: cblab = newlab();
132: cclab = newlab();
133: lab1 = here();
134: lex();
135: statement();
136: label(cclab);
137: dbstat(s, line);
138: mustbe(WHILE);
139: tp = pexpr();
140: truth(tp);
141: tput(TEXPR, lab1, tp);
142: label(cblab);
143: mustbe(SEMI);
144: cclab = sclab;
145: cblab = sblab;
146: break;
147:
148: case WHILE:
149: sblab = cblab;
150: sclab = cclab;
151: cblab = newlab();
152: cclab = here();
153: lex();
154: tp = pexpr();
155: truth(tp);
156: tput(FEXPR, cblab, tp);
157: statement();
158: jump(cclab);
159: label(cblab);
160: cclab = sclab;
161: cblab = sblab;
162: break;
163:
164: case SWITCH:
165: lex();
166: tp = pexpr();
167: tt = tltype(tp);
168: if (tt > T_UINT)
169: cerror("switch of non integer");
170: if (tt != T_INT) {
171: rp = NULL;
172: if (tt == T_PTR)
173: rp = bzcon(psize(tp));
174: tp = bconvert(tp, T_INT, NULL, NULL, rp);
175: }
176: tput(SEXPR, 0, tp);
177: ssbp = sbp;
178: sbp = (SBLOCK *) new(sizeof(SBLOCK));
179: sbp->sb_dlab = 0;
180: sbp->sb_ncase = 0;
181: sblab = cblab;
182: cblab = newlab();
183: statement();
184: jump(cblab);
185: if (sbp->sb_dlab==0 && sbp->sb_ncase==0)
186: cwarn("empty switch");
187: if (sbp->sb_dlab == 0)
188: sbp->sb_dlab = cblab;
189: bput(SBODY);
190: iput((ival_t) sbp->sb_dlab);
191: iput((ival_t) sbp->sb_ncase);
192: for (i=0; i<sbp->sb_ncase; ++i) {
193: iput((ival_t) sbp->sb_case[i].sc_val);
194: iput((ival_t) sbp->sb_case[i].sc_lab);
195: }
196: label(cblab);
197: cblab = sblab;
198: free((char *) sbp);
199: sbp = ssbp;
200: break;
201:
202: case FOR:
203: lex();
204: mustbe(LPAREN);
205: newtree(sizeof(TREE));
206: itree = NULL;
207: if (s != SEMI)
208: itree = expr();
209: mustbe(SEMI);
210: ctree = NULL;
211: if (s != SEMI) {
212: ctree = expr();
213: truth(ctree);
214: }
215: mustbe(SEMI);
216: stree = NULL;
217: if (s != RPAREN)
218: stree = expr();
219: mustbe(RPAREN);
220: sblab = cblab;
221: sclab = cclab;
222: cblab = newlab();
223: cclab = newlab();
224: if (itree != NULL) {
225: tput(EEXPR, 0, itree);
226: }
227: if (stree != NULL)
228: jump(lab1 = newlab());
229: label(cclab);
230: if (stree != NULL) {
231: tput(EEXPR, 0, stree);
232: label(lab1);
233: }
234: if (ctree != NULL) {
235: tput(FEXPR, cblab, ctree);
236: }
237: statement();
238: jump(cclab);
239: label(cblab);
240: cclab = sclab;
241: cblab = sblab;
242: break;
243:
244: case RETURN:
245: lex();
246: if (s != SEMI) {
247: newtree(sizeof(TREE));
248: tp = expr();
249: lp = talloc();
250: lp->t_op = CONVERT;
251: lp->t_type = cfsym->s_type;
252: lp->t_dp = cfsym->s_dp->d_dp; /* Skip D_FUNC */
253: lp->t_ip = cfsym->s_ip;
254: if (lp->t_dp==NULL && lp->t_type==T_VOID) {
255: cerror("return(e) illegal in void function");
256: mustbe(SEMI);
257: break;
258: }
259: if ((tltype(lp)==T_STRUCT || tltype(tp)==T_STRUCT)
260: && (lp->t_type!=tp->t_type||lp->t_dp!=tp->t_dp||lp->t_ip!=tp->t_ip)) {
261: cerror("return type/function type mismatch");
262: mustbe(SEMI);
263: break;
264: }
265: if (bitcompat(tltype(lp), tltype(tp)))
266: adjust(tp, lp->t_type, lp->t_dp, lp->t_ip);
267: else {
268: lp->t_lp = tp;
269: tp = lp;
270: }
271: tput(REXPR, 0, tp);
272: }
273: jump(cflab);
274: mustbe(SEMI);
275: break;
276:
277: case ID:
278: if (spnextis(':')) {
279: dolabel();
280: lex();
281: lex();
282: goto loop;
283: }
284:
285: default:
286: newtree(sizeof(TREE));
287: tp = expr();
288: tput(EEXPR, 0, tp);
289: mustbe(SEMI);
290: }
291: }
292:
293: /*
294: * Check if the given tree can be used in a truth value context.
295: * Put out the appropriate diagnostics.
296: * What does this have to do with stat()?
297: */
298: truth(tp)
299: TREE *tp;
300: {
301: register int tt, op;
302:
303: tt = tltype(tp);
304: op = tp->t_op;
305: if (tt>=T_STRUCT && tt<=T_FUNION)
306: cerror("structure or union used in truth context");
307: if (incpp)
308: return;
309: if (isvariant(VSCCON) && (op==ICON || op==LCON || op==DCON))
310: cstrict("constant used in truth context");
311: if (isvariant(VSRTVC)) {
312: if ((tt>=T_PTR && tt<=T_DOUBLE)
313: || (op==EQ && tp->t_lp->t_type==T_DOUBLE))
314: cstrict("risky type in truth context");
315: }
316: }
317:
318: /*
319: * Read an expression enclosed in parentheses.
320: * Used to read the control expressions in 'if', 'do', 'while' and 'switch'.
321: */
322: TREE *
323: pexpr()
324: {
325: register TREE *tp;
326:
327: mustbe(LPAREN);
328: newtree(sizeof(TREE));
329: tp = expr();
330: mustbe(RPAREN);
331: return (tp);
332: }
333:
334: /*
335: * Labels.
336: */
337: dolabel()
338: {
339: register SYM *sp;
340: register int c;
341:
342: sp = deflookup(SL_LAB, 2);
343: c = sp->s_class;
344: if (c==C_NONE || c==C_FREF) {
345: if (c == C_NONE)
346: sp->s_value = newlab();
347: sp->s_class = C_LAB;
348: label(sp->s_value);
349: dblabel(sp);
350: } else
351: cerror("illegal label \"%s\"", sp->s_id);
352: }
353:
354: /*
355: * The dreaded 'goto' statement.
356: */
357: dogoto()
358: {
359: register SYM *sp;
360: register int c;
361:
362: sp = deflookup(SL_LAB, 2);
363: c = sp->s_class;
364: if (c == C_NONE) {
365: sp->s_class = C_FREF;
366: sp->s_value = newlab();
367: } else if (c!=C_LAB && c!=C_FREF)
368: cerror("identifier \"%s\" is not a label", sp->s_id);
369: jump(sp->s_value);
370: sp->s_flag |= S_USED;
371: }
372:
373: /*
374: * Append a new case to the current switch,
375: * adjusting the size of the switch block if necessary and possible.
376: */
377: newcase(v)
378: ival_t v;
379: {
380: SBLOCK *ssbp;
381: register SCASE *scp, *ocp;
382: register int i;
383:
384: i = sbp->sb_ncase;
385: scp = sbp->sb_case;
386: while (--i >= 0) {
387: if (scp->sc_val == v) {
388: cerror("duplicated case constant");
389: return;
390: } else
391: scp += 1;
392: }
393: i = sbp->sb_ncase;
394: scp = &sbp->sb_case[i];
395: if ((i % 32) == 0) {
396: ssbp = sbp;
397: sbp = new(sizeof(SBLOCK) + (i+32) * sizeof(SCASE));
398: sbp->sb_ncase = ssbp->sb_ncase;
399: sbp->sb_dlab = ssbp->sb_dlab;
400: scp = sbp->sb_case;
401: ocp = ssbp->sb_case;
402: while (--i >= 0) {
403: scp->sc_val = ocp->sc_val;
404: scp->sc_lab = ocp->sc_lab;
405: scp += 1;
406: ocp += 1;
407: }
408: free((char *) ssbp);
409: scp = &sbp->sb_case[sbp->sb_ncase];
410: }
411: scp->sc_val = v;
412: scp->sc_lab = here();
413: sbp->sb_ncase += 1;
414: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.