|
|
1.1 root 1: /*ident "@(#)ctrans:src/dcl2.c 1.3.4.22" */
2: /**************************************************************************
3:
4: C++ source for cfront, the C++ compiler front-end
5: written in the computer science research center of Bell Labs
6:
7: Copyright (c) 1984 AT&T, Inc. All Rights Reserved
8: THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T, INC.
9:
10: dcl2.c:
11:
12: *************************************************************************/
13:
14: #include "cfront.h"
15: #include "size.h"
16:
17: Pname conv_dominates(Pname on1, Pname on2)
18: /*
19: compare for duplicates and dominance:
20:
21: on1 and on2 are two conversion operator functions
22: return the the one that dominates the other (according to the
23: class hierarchy) otherwise 0 (0 thus indicats ambiguous conversion)
24: */
25: {
26: Ptype r1 = Pfct(on1->tp)->returns;
27: Ptype r2 = Pfct(on2->tp)->returns;
28: //error('d',"conv_dominates(%n,%n)",on1,on2);
29: if (r1==r2 || r1->check(r2,0)==0) return on1;
30: Pptr p1 = r1->is_ptr_or_ref();
31: Pptr p2 = r2->is_ptr_or_ref();
32: if (p1 && p2) {
33: Pname cn1 = p1->typ->is_cl_obj();
34: Pname cn2 = p2->typ->is_cl_obj();
35: if (cn1 && cn2) {
36: // is_cl_obj() returns b_name
37: // Pclass c1 = Pclass(Pbase(cn1->tp)->b_name->tp);
38: // Pclass c2 = Pclass(Pbase(cn2->tp)->b_name->tp);
39: Pclass c1 = Pclass(cn1->tp);
40: Pclass c2 = Pclass(cn2->tp);
41: if (c1 && c2) {
42: if (c1==c2 || c1->has_base(c2))
43: return on1;
44: else if (c2->has_base(c1))
45: return on2;
46: }
47: }
48: }
49: return 0;
50: }
51:
52:
53: Pstmt curr_loop;
54: Pstmt curr_switch;
55: Pblock curr_block;
56:
57: void stmt::reached()
58: {
59: register Pstmt ss = s_list;
60:
61: if (ss == 0) return;
62:
63: switch (ss->base) {
64: case LABEL:
65: case CASE:
66: case DEFAULT:
67: break;
68: default:
69: error('w',"S after%k not reached",base);
70: for (; ss; ss=ss->s_list) { // delete unreacheable code
71: switch (ss->base) {
72: case LABEL:
73: case CASE:
74: case DEFAULT: // reachable
75: s_list = ss;
76: return;
77: case DCL: // the dcl may be used later
78: // keep to avoid cascading errors
79: case IF:
80: case DO:
81: case WHILE:
82: case SWITCH:
83: case FOR:
84: case BLOCK: // may hide a label
85: s_list = ss;
86: return;
87: }
88: }
89: s_list = 0;
90: }
91: }
92:
93: bit arg_err_suppress;
94:
95: Pexpr check_cond(Pexpr e, TOK b, Ptable tbl)
96: {
97: //error('d',"check_cond(%k %k) tbl %d",e->base,b,tbl);
98: Pname cn;
99:
100: if (e == dummy) error("empty condition for %k",b);
101:
102: if (cn = e->tp->is_cl_obj()) {
103: Pclass cl = Pclass(cn->tp);
104: int i = 0;
105: Pname found = 0;
106: for (Pname on = cl->conv; on; on=on->n_list) {
107: Pfct f = Pfct(on->tp);
108: Ptype t = f->returns;
109: xx:
110: switch (t->base) {
111: case TYPE:
112: t = Pbase(t)->b_name->tp;
113: goto xx;
114: case FLOAT:
115: case DOUBLE:
116: case LDOUBLE:
117: case PTR:
118: if (b == DEREF) break;
119: case CHAR:
120: case SHORT:
121: case INT:
122: case LONG:
123: case EOBJ:
124: // if (found==0 || found->tp->check(on->tp,0)) {
125: //error('d',"found %n on %n",found,on);
126: { Pname xx = found;
127: if (found == 0) {
128: i = 1;
129: found = on;
130: }
131: else if ((found = conv_dominates(found,on)) == 0) {
132: i = 2;
133: found = on;
134: error("two conversions for%nO in%kE: %n and %n",cn,b,xx,on);
135: return e;
136: }
137: }
138: }
139: }
140: //error('d',"i %d",i);
141: switch (i) {
142: case 0:
143: error("%nO in%kE",cn,b);
144: return e;
145: /*
146: case 1:
147: { Pname xx = new name(found->string);
148: Pref r = new ref(DOT,e,xx);
149: Pexpr rr = r->typ(tbl);
150: Pexpr c = new expr(G_CALL,rr,0);
151:
152: if (e->lval(0)) {
153: // Pref r = new ref(DOT,e,found);
154: // r->tp = found->tp;
155: // Pexpr c = new expr(G_CALL,r,0);
156: // c->fct_name = found;
157: return c->typ(tbl);
158: }
159: else { // (temp=init,temp.coerce())
160: Pname tmp = make_tmp('U',e->tp,tbl);
161: Pexpr ass = init_tmp(tmp,e,tbl);
162: // Pref r = new ref(DOT,tmp,found);
163: // Pexpr rr = r->typ(tbl);
164: // Pexpr c = new expr(G_CALL,rr,0);
165: // c->fct_name = found;
166: ass = new expr(CM,ass,c);
167: return ass->typ(tbl);
168: }
169: }
170: */
171: case 1:
172: { Pname xx = new name(found->string);
173: Pexpr c;
174:
175: if (e->lval(0)) {
176: Pref r = new ref(DOT,e,xx);
177: Pexpr rr = r->typ(tbl);
178: c = new expr(G_CALL,rr,0);
179: }
180: else { // (temp=init,temp.coerce())
181: Pname tmp = make_tmp('U',e->tp,tbl);
182: Pexpr ass = init_tmp(tmp,e,tbl);
183: Pref r = new ref(DOT,tmp,xx);
184: Pexpr rr = r->typ(tbl);
185: c = new expr(G_CALL,rr,0);
186: c = new expr(CM,ass,c);
187: }
188: return c->typ(tbl);
189: }
190: // default:
191: // error("%d possible conversions for%nO in%kE",i,cn,b);
192: // return e;
193: }
194:
195: }
196: if (e->tp->memptr()) {
197: e = new mdot("i",e);
198: e->i1 = 9;
199: e = new expr(NE,e,zero);
200: }
201: else if (e->tp->num_ptr(b) == FCT)
202: error("%k(F)",b);
203: return e;
204: }
205:
206: void stmt::dcl()
207: /*
208: typecheck statement "this" in scope "curr_block->tbl"
209: */
210: {
211: Pstmt ss;
212: Pname n;
213: Pname nn;
214: Pstmt ostmt = Cstmt;
215: for (ss=this; ss; ss=ss->s_list) {
216: Pstmt old_loop, old_switch;
217: Cstmt = ss;
218: Ptable tbl = curr_block->memtbl;
219: //error('d',"stmt::dcl %k",ss->base);
220: switch (ss->base) {
221: case BREAK:
222: inline_restr |= 16;
223: if (curr_loop==0 && curr_switch==0)
224: error("break not in loop or switch");
225: ss->reached();
226: break;
227:
228: case CONTINUE:
229: inline_restr |= 32;
230: if (curr_loop == 0) error("continue not in loop");
231: ss->reached();
232: break;
233:
234: case DEFAULT:
235: if (curr_switch == 0) {
236: error("default not in switch");
237: break;
238: }
239: if (curr_switch->has_default) error("two defaults in switch");
240: curr_switch->has_default = ss;
241: ss->s->s_list = ss->s_list;
242: ss->s_list = 0;
243: ss->s->dcl();
244: break;
245:
246: case SM:
247: { if (ss->e ==0) break;
248: TOK b = ss->e->base;
249: switch (b) {
250: case DUMMY:
251: ss->e = 0;
252: break;
253: // check for unused results
254: // don't check operators that are likely
255: // to be overloaded to represent "actions":
256: // ! ~ < <= > >= << >>
257: case EQ:
258: case NE:
259: case PLUS:
260: case MINUS:
261: case REF:
262: case DOT:
263: case MUL:
264: case DIV:
265: case ADDROF:
266: case AND:
267: case OR:
268: case ER:
269: case DEREF:
270: case ANDAND:
271: case OROR:
272: case NAME:
273: case VALUE:
274: if (ss->e->tp) break; // avoid looking at generated code
275: ss->e = ss->e->typ(tbl);
276: if (ss->e->base == CALL) break;
277: if (ss->e->tp->base != VOID) {
278: error('w',"result of%kE not used",b);
279: if (ss->e->not_simple()==0) ss->e = dummy;
280: }
281: break;
282: default:
283: ss->e = ss->e->typ(tbl);
284: }
285: break;
286: }
287: case RETURN:
288: { Pname fn = cc->nof;
289: Pfct f = Pfct(fn->tp);
290: Ptype rt = f->returns;
291: Pexpr v = ss->e;
292: //error('d',"rt %t",rt);
293: if (v != dummy) {
294: while (rt->base == TYPE) rt = Pbase(rt)->b_name->tp;
295: extern ref_initializer;
296: if (rt->base == RPTR) {
297: ref_initializer++;
298: v = v->typ(tbl);
299: ref_initializer--;
300: } else
301: v = v->typ(tbl);
302:
303: if (fn->n_oper==CTOR
304: || fn->n_oper==DTOR
305: || (rt->base==VOID && v->tp!=void_type)) {
306: error("unexpected return value");
307: // refuse to return the value:
308: ss->e = dummy;
309: }
310: else {
311: lx:
312: switch (rt->base) {
313: case TYPE:
314: rt = Pbase(rt)->b_name->tp;
315: goto lx;
316: case RPTR:
317: switch (v->base) {
318: case NAME:
319: if (Pname(v)->n_scope==FCT
320: || Pname(v)->n_scope==ARG)
321: error('w',"R to localV returned");
322: break;
323: case ICON:
324: case CCON:
325: case FCON:
326: case STRING:
327: if (Pptr(rt)->typ->tconst()==0)
328: error('w',"R to literal returned");
329: }
330: v = ref_init(Pptr(rt),v,tbl);
331: if (v->base==G_CM
332: && v->e2->base==G_ADDROF
333: && v->e2->e2->base==NAME)
334: error('w',"R to temporary returned (return value is not lvalue or of wrongT)");
335: case ANY:
336: break;
337: case COBJ:
338: if (v->base == DEREF) {
339: Pexpr v1 = v->e1;
340: if (v1->base==CAST) {
341: Pexpr v2 = v1->e1;
342: if (v2->base == G_CM) { // *(T)(e1,e2) => (e1,*(T)e2)
343: Pexpr v3 = v2->e2;
344: v2->e2 = v;
345: v2->tp = v->tp;
346: v = v2;
347: v1->e1 = v3;
348: }
349: }
350: }
351: if (f->f_result) {
352: if (v->base==G_CM && rt->check(v->tp,0/*ASSIGN*/)==0)
353: v = replace_temp(v,f->f_result);
354: else {
355: v = class_init(f->f_result->contents(),rt,v,tbl);
356: Pname rcn = rt->is_cl_obj();
357: if (Pclass(rcn->tp)->has_itor()==0) {
358: // can happen for virtuals and for user defined conversions
359: v->tp = rt;
360: v = new expr(ASSIGN,f->f_result->contents(),v);
361: v->tp = rt;
362: }
363: }
364: }
365: else
366: v = class_init(0,rt,v,tbl);
367: break;
368: case PTR:
369: { Pexpr x = v;
370: v = ptr_init(Pptr(rt),v,tbl);
371: if (v->base == ADDROF
372: && v->e2->base == NAME
373: && Pname(v->e2)->n_stclass == AUTO)
374: error('w',"P to local variable%n returned",Pname(v->e2));
375: // if (v==x ||v->e2==x) goto def;
376: if (Pchecked == 0) goto def;
377: goto ret_save;
378: // break;
379: }
380: case INT:
381: case CHAR:
382: case LONG:
383: case SHORT:
384: if (Pbase(rt)->b_unsigned
385: && v->base==UMINUS
386: && v->e2->base==ICON)
387: error('w',"negative retured fromF returning unsigned");
388: default:
389: def:
390: {
391: Pexpr x = try_to_coerce(rt,v,"return value",tbl);
392: if (x)
393: v = x;
394: else if (rt->check(v->tp,ASSIGN))
395: error("bad return valueT for%n:%t (%tX)",fn,v->tp,rt);
396: }
397:
398: }
399: ret_save:
400: ss->ret_tp = rt;
401: ss->e = v;
402: }
403: }
404: else {
405: if (rt->base != VOID) error("return valueX");
406: }
407: ss->reached();
408: break;
409: }
410:
411: case DO: // in DO the stmt is before the test
412: inline_restr |= 8;
413: old_loop = curr_loop;
414: curr_loop = ss;
415: if (ss->s->base == DCL) error("D as onlyS in do-loop");
416: ss->s->dcl();
417: ss->e = ss->e->typ(tbl);
418: ss->e = check_cond(ss->e,DO,tbl);
419: curr_loop = old_loop;
420: break;
421:
422: case WHILE:
423: inline_restr |= 8;
424: old_loop = curr_loop;
425: curr_loop = ss;
426: ss->e = ss->e->typ(tbl);
427: ss->e = check_cond(ss->e,WHILE,tbl);
428: if (ss->s->base == DCL) error("D as onlyS in while-loop");
429: ss->s->dcl();
430: curr_loop = old_loop;
431: break;
432:
433: case SWITCH:
434: { int ne = 0;
435: inline_restr |= 4;
436: old_switch = curr_switch;
437: curr_switch = ss;
438: ss->e = ss->e->typ(tbl);
439: ss->e = check_cond(ss->e,SWITCH,tbl);
440: if (ss->s->base == DCL) error("D as onlyS in switchS");
441: { Ptype tt = ss->e->tp;
442: sii:
443: switch (tt->base) {
444: case TYPE:
445: tt = Pbase(tt)->b_name->tp; goto sii;
446: case EOBJ:
447: ne = Penum(Pbase(tt)->b_name->tp)->no_of_enumerators;
448: case ZTYPE:
449: case ANY:
450: case CHAR:
451: case SHORT:
452: case INT:
453: case LONG:
454: case FIELD:
455: break;
456: default:
457: error("%t switchE",ss->e->tp);
458: }
459: }
460: ss->s->dcl();
461: if (ne) { /* see if the number of cases is "close to"
462: but not equal to the number of enumerators
463: */
464: int i = 0;
465: Pstmt cs;
466: for (cs=ss->case_list; cs; cs=cs->case_list) i++;
467: if (i && i!=ne) {
468: if (ne < i) {
469: ee: error('w',"switch (%t)W %d cases (%d enumerators)",ss->e->tp,i,ne);
470: }
471: else {
472: switch (ne-i) {
473: case 1: if (3<ne) goto ee;
474: case 2: if (7<ne) goto ee;
475: case 3: if (23<ne) goto ee;
476: case 4: if (60<ne) goto ee;
477: case 5: if (99<ne) goto ee;
478: }
479: }
480: }
481: }
482: curr_switch = old_switch;
483: break;
484: }
485: case CASE:
486: if (curr_switch == 0) {
487: error("case not in switch");
488: break;
489: }
490: ss->e = ss->e->typ(tbl);
491: ss->e->tp->num_ptr(CASE);
492: { Ptype tt = ss->e->tp;
493: iii:
494: switch (tt->base) {
495: case TYPE:
496: tt = Pbase(tt)->b_name->tp; goto iii;
497: case ZTYPE:
498: case ANY:
499: case CHAR:
500: case SHORT:
501: case INT:
502: case LONG:
503: case EOBJ:
504: Neval = 0;
505: long i = ss->e->eval();
506: if (Neval == 0) {
507: Pstmt cs;
508: if (largest_int<i) error("long case value");
509: for (cs=curr_switch->case_list; cs; cs=cs->case_list) {
510: if (cs->case_value == i) error("case %d used twice in switch",i);
511: }
512: ss->case_value = int(i);
513: ss->case_list = curr_switch->case_list;
514: curr_switch->case_list = ss;
515: }
516: else
517: error("bad case label: %s",Neval);
518: break;
519: default:
520: error("%t caseE",ss->e->tp);
521: }
522: }
523: // if (1) {
524: // Neval = 0;
525: // long i = ss->e->eval();
526: // if (Neval == 0) {
527: // Pstmt cs;
528: // if (largest_int<i) error("long case value");
529: // for (cs=curr_switch->case_list; cs; cs=cs->case_list) {
530: // if (cs->case_value == i) error("case %d used twice in switch",i);
531: // }
532: // ss->case_value = int(i);
533: // ss->case_list = curr_switch->case_list;
534: // curr_switch->case_list = ss;
535: // }
536: // else
537: // error("bad case label: %s",Neval);
538: // }
539: if (ss->s->s_list) error('i',"case%k",ss->s->s_list->base);
540: ss->s->s_list = ss->s_list;
541: ss->s_list = 0;
542: ss->s->dcl();
543: break;
544:
545: case GOTO:
546: inline_restr |= 2;
547: ss->reached();
548: case LABEL:
549: /* Insert label in function mem table;
550: labels have function scope.
551: */
552: n = ss->d;
553: nn = cc->ftbl->insert(n,LABEL);
554:
555: /* Set a ptr to the mem table corresponding to the scope
556: in which the label actually occurred. This allows the
557: processing of goto's in the presence of ctors and dtors
558: */
559: if (ss->base == LABEL) {
560: nn->n_realscope = curr_block->memtbl;
561: inline_restr |= 1;
562: }
563:
564: if (Nold) {
565: if (ss->base == LABEL) {
566: if (nn->n_initializer) error("twoDs of label%n",n);
567: nn->n_initializer = (Pexpr)1;
568: }
569: if (n != nn) ss->d = nn;
570: }
571: else {
572: if (ss->base == LABEL) nn->n_initializer = (Pexpr)1;
573: nn->where = ss->where;
574: }
575: if (ss->base == GOTO)
576: nn->use();
577: else {
578: if (ss->s->s_list) error('i',"label%k",ss->s->s_list->base);
579: ss->s->s_list = ss->s_list;
580: ss->s_list = 0;
581: nn->assign();
582: }
583: if (ss->s) ss->s->dcl();
584: break;
585:
586: case IF:
587: {
588: Pexpr ee = ss->e->typ(tbl);
589: if (ee->base == ASSIGN) {
590: Neval = 0;
591: (void)ee->e2->eval();
592: if (Neval == 0)
593: error('w',"constant assignment in condition");
594: }
595: ss->e = ee = check_cond(ee,IF,tbl);
596:
597: if (ss->s->base == DCL) error("D as onlyS after `if'");
598:
599: // pointer to member returns with a tp set to 0
600: if ( ee->tp ) switch (ee->tp->base) {
601: case INT:
602: case EOBJ:
603: case ZTYPE:
604: { long i;
605: Neval = 0;
606: i = ee->eval();
607:
608: if (Neval == 0) {
609: Pstmt sl = ss->s_list;
610: if (i) {
611: DEL(ss->else_stmt);
612: ss->s->dcl();
613: *ss = *ss->s;
614: }
615: else {
616: DEL(ss->s);
617: if (ss->else_stmt) {
618: ss->else_stmt->dcl();
619: *ss = *ss->else_stmt;
620: }
621: else {
622: ss->base = SM;
623: ss->e = dummy;
624: ss->s = 0;
625: }
626: }
627: ss->s_list = sl;
628: continue;
629: }
630: }
631: }
632: ss->s->dcl();
633: if (ss->else_stmt) {
634: if (ss->else_stmt->base == DCL) error("D as onlyS after `else'");
635: ss->else_stmt->dcl();
636: }
637: break;
638: }
639: case FOR:
640: inline_restr |= 8;
641: old_loop = curr_loop;
642: curr_loop = ss;
643: if (ss->for_init) {
644: Pstmt fi = ss->for_init;
645: switch (fi->base) {
646: case SM:
647: if (fi->e == dummy) {
648: ss->for_init = 0;
649: break;
650: }
651: default:
652: fi->dcl();
653: break;
654: case DCL:
655: // if ()
656: // {
657: // // for (dcl; e1; e2) stmt1 stmt2
658: // // => { dcl; for( ; e1; e2) stmt1 } stmt2
659: // ss->base = BLOCK;
660: // ss->d = fi->d;
661: // ss->s = new forstmt(ss->where,new estmt(SM,ss->where,dummy,0),ss->e,ss->e2,ss->s);
662: // Pblock(ss)->dcl(tbl);
663: // continue;
664: // }
665: // else {
666: fi->dcl();
667: switch (fi->base) {
668: case BLOCK:
669: {
670: // { ... for( { a } b ; c) d ; e }
671: // => { ... { a for ( ; b ; c) d ; e }}
672: Pstmt tmp = new stmt (SM,curloc,0);
673: *tmp = *ss; // tmp = for
674: tmp->for_init = 0;
675: *ss = *fi; // ss = { }
676: if (ss->s)
677: ss->s->s_list = tmp;
678: else
679: ss->s = tmp;
680: curr_block = Pblock(ss);
681: tbl = curr_block->memtbl;
682: Cstmt = ss = tmp; // rest of for and s_list
683: break;
684: }
685: }
686: // }
687:
688: }
689: }
690: if (ss->e == dummy)
691: ss->e = 0;
692: else {
693: ss->e = ss->e->typ(tbl);
694: ss->e = check_cond(ss->e,FOR,tbl);
695: }
696: if (ss->s->base == DCL) error("D as onlyS in for-loop");
697: ss->s->dcl();
698: ss->e2 = (ss->e2 == dummy) ? 0 : ss->e2->typ(tbl);
699: curr_loop = old_loop;
700: break;
701:
702: case DCL: /* declaration after statement */
703: {
704: /* collect all the contiguous DCL nodes from the
705: head of the s_list. find the next statement
706: */
707: int non_trivial = 0;
708: int count = 0;
709: Pname tail = ss->d;
710: for (Pname nn=tail; nn; nn=nn->n_list) {
711: // find tail;
712: // detect non-trivial declarations
713: count++;
714:
715: if (nn->n_list) tail = nn->n_list;
716: Pname n = tbl->look(nn->string,0);
717:
718: if (n && n->n_table==tbl) non_trivial = 2;
719: if (non_trivial == 2) continue;
720: if ((nn->n_sto==STATIC && nn->tp->base!=FCT)
721: || nn->tp->is_ref()
722: || (nn->tp->tconst() && fct_const==0)) {
723: non_trivial = 2;
724: continue;
725: }
726:
727: Pexpr in = nn->n_initializer;
728: if (in)
729: switch (in->base) {
730: case ILIST:
731: case STRING:
732: non_trivial = 2;
733: continue;
734: default:
735: non_trivial = 1;
736: }
737: Pname cln = nn->tp->is_cl_obj();
738: if (cln == 0) cln = cl_obj_vec;
739: if (cln == 0) continue;
740: if (Pclass(cln->tp)->has_ctor()) {
741: non_trivial = 2;
742: continue;
743: }
744: if (Pclass(cln->tp)->has_dtor()) non_trivial = 2;
745: }
746:
747: while( ss->s_list && ss->s_list->base==DCL ) {
748: Pstmt sx = ss->s_list;
749: tail = tail->n_list = sx->d; // add to tail
750: for (nn=sx->d; nn; nn=nn->n_list) {
751: // find tail;
752: // detect non-trivial declarations
753: count++;
754: if (nn->n_list) tail = nn->n_list;
755: Pname n = tbl->look(nn->string,0);
756: if (n && n->n_table==tbl) non_trivial = 2;
757: if (non_trivial == 2) continue;
758: if ((nn->n_sto==STATIC && nn->tp->base!=FCT)
759: || nn->tp->is_ref()
760: || (nn->tp->tconst() && fct_const==0)) {
761: non_trivial = 2;
762: continue;
763: }
764: Pexpr in = nn->n_initializer;
765: if (in)
766: switch (in->base) {
767: case ILIST:
768: case STRING:
769: non_trivial = 2;
770: continue;
771: }
772: non_trivial = 1;
773: Pname cln = nn->tp->is_cl_obj();
774: if (cln == 0) cln = cl_obj_vec;
775: if (cln == 0) continue;
776: if (Pclass(cln->tp)->has_ctor()) {
777: non_trivial = 2;
778: continue;
779: }
780: if (Pclass(cln->tp)->has_dtor()) continue;
781: }
782: ss->s_list = sx->s_list;
783: /* delete sx; */
784: }
785:
786: Pstmt next_st = ss->s_list;
787: if (non_trivial==2 // must
788: || (non_trivial==1 // might
789: && ( curr_block->own_tbl==0 // why not?
790: || inline_restr&3 /* label seen */)
791: )
792: ) {
793: if (curr_switch && non_trivial==2) {
794: Pstmt cs = curr_switch->case_list;
795: Pstmt ds = curr_switch->has_default;
796: Pstmt bl;
797: if (cs == 0)
798: bl = ds;
799: else if (ds == 0)
800: bl = cs;
801: else if (cs->where.line<ds->where.line)
802: bl = ds;
803: else
804: bl = cs;
805:
806: if ((bl==0 || bl->s->base!=BLOCK) && curr_switch->s->memtbl==tbl)
807: error('s',"non trivialD in switchS (try enclosing it in a block)");
808: }
809:
810: /* Create a new block,
811: put all the declarations at the head,
812: and the remainder of the slist as the
813: statement list of the block.
814: */
815: ss->base = BLOCK;
816:
817: /* check that there are no redefinitions since the last
818: "real" (user-written, non-generated) block
819: */
820: for( nn=ss->d; nn; nn=nn->n_list ) {
821: Pname n;
822: if( curr_block->own_tbl
823: && (n=curr_block->memtbl->look(nn->string,0))
824: && n->n_table->real_block==curr_block->memtbl->real_block
825: && n->tp->base!=FCT && n->tp->base!=OVERLOAD
826: && nn->lex_level == n->lex_level )
827: error("twoDs of%n",n);
828: }
829:
830: /* attach the remainder of the s_list
831: as the statement part of the block.
832: */
833: ss->s = next_st;
834: ss->s_list = 0;
835:
836: /* create the table in advance, in order to set the
837: real_block ptr to that of the enclosing table
838: */
839: ss->memtbl = new table(count+4,tbl,0);
840: ss->memtbl->real_block = curr_block->memtbl->real_block;
841: Pblock(ss)->dcl(ss->memtbl);
842: }
843: else { /* to reduce the number of symbol tables,
844: do not make a new block,
845: instead insert names in enclosing block,
846: and make the initializers into expression
847: statements.
848: */
849: Pstmt sss = ss;
850: for( nn=ss->d; nn; nn=nn->n_list ) {
851: Pname n;
852: //error('d',"nn %n",nn);
853: if( curr_block->own_tbl
854: && (n=curr_block->memtbl->look(nn->string,0))
855: && n->n_table->real_block==curr_block->memtbl->real_block
856: && n->tp->base!=FCT && n->tp->base!=OVERLOAD
857: && nn->lex_level == n->lex_level )
858: {
859: printf( "\ndump tables: bl_level: %d", bl_level );
860: /*
861: //extern void display_table( Ptable,int=0 );display_table(curr_block->memtbl);
862: //extern void display_name( Pname ); display_name( nn ); display_name(n);
863: */
864: error("twoDs of%n",n);
865: }
866: //error("twoDs of%n",n);
867: /*Pname */n = nn->dcl(tbl,FCT);
868:
869: if (n == 0) {
870: if (ss) {
871: ss->base = SM;
872: ss->e = 0;
873: }
874: continue;
875: }
876:
877: Pexpr in = n->n_initializer;
878: n->n_initializer = 0;
879:
880: if (ss) {
881: sss->base = SM;
882: ss = 0;
883: }
884: else
885: sss = sss->s_list = new estmt(SM,sss->where,0,0);
886: if (in) {
887: switch (in->base) {
888: case G_CALL: /* constructor? */
889: {
890: Pname fn = in->fct_name;
891: if (fn && fn->n_oper==CTOR) break;
892: }
893: default:
894: in = new expr(ASSIGN,n,in);
895: in->tp = n->tp;
896: }
897: // sss->e = in->typ(tbl);
898: sss->e = in;
899: }
900: else
901: sss->e = dummy;
902: }
903:
904: ss = sss;
905: ss->s_list = next_st;
906: }
907: break;
908: }
909:
910: case BLOCK:
911: Pblock(ss)->dcl(tbl);
912: break;
913:
914: case ASM:
915: /* save string */
916: {
917: char* s = (char*)ss->e;
918: int ll = strlen(s);
919: char* s2 = new char[ll+1];
920: strcpy(s2,s);
921: ss->e = Pexpr(s2);
922: break;
923: }
924: default:
925: error('i',"badS(%p %d)",ss,ss->base);
926: }
927: }
928: Cstmt = ostmt;
929: }
930:
931: extern int in_class_dcl;
932: void block::dcl(Ptable tbl)
933: /*
934: Note: for a block without declarations memtbl denotes the table
935: for the enclosing scope.
936: A function body has its memtbl created by fct::dcl().
937: */
938: {
939: int bit_old = bit_offset;
940: int byte_old = byte_offset;
941: int max_old = max_align;
942: Pblock block_old = curr_block;
943:
944: if (base != BLOCK) error('i',"block::dcl(%d)",base);
945:
946: curr_block = this;
947: //error('d',"block %k %k",d?d->base:0,s?s->base:0);
948: if (d) {
949: own_tbl = 1;
950: if (memtbl == 0) {
951: int nmem = d->no_of_names()+4;
952: memtbl = new table(nmem,tbl,0);
953: memtbl->real_block = this;
954: /* this is a "real" block from the
955: source text, and not one created by DCL's
956: inside a block. */
957: }
958: else
959: if (memtbl != tbl) error('i',"block::dcl(?)");
960:
961: Pname nx;
962: for (Pname n=d; n; n=nx) {
963: nx = n->n_list;
964: n->dcl(memtbl,FCT);
965: switch (n->tp->base) {
966: case CLASS:
967: case ANON:
968: case ENUM:
969: break;
970: default:
971: delete n;
972: }
973: }
974: }
975: else
976: memtbl = tbl;
977:
978: if (s) {
979: Pname odcl = Cdcl;
980: Pname m;
981: int i;
982:
983: s->dcl();
984:
985: if (own_tbl)
986: for (m=memtbl->get_mem(i=1); m; m=memtbl->get_mem(++i)) {
987: Ptype t = m->tp;
988:
989: if (in_class_dcl) m->lex_level -= 1;
990:
991: if (t == 0) {
992: if (m->n_assigned_to == 0)
993: error("label %sU",m->string);
994: if (m->n_used == 0)
995: error('w',"label %s not used", m->string);
996: continue;
997: }
998: ll:
999: switch (t->base) {
1000: case TYPE: t = Pbase(t)->b_name->tp; goto ll;
1001: case CLASS:
1002: case ANON:
1003: case ENUM:
1004: case FCT:
1005: case VEC: continue;
1006: }
1007:
1008: if (m->n_addr_taken == 0) {
1009: if (m->n_used) {
1010: if (m->n_assigned_to) {
1011: }
1012: else {
1013: switch (m->n_scope) {
1014: case FCT:
1015: Cdcl = m;
1016: if (m->string[0] != '_' && m->string[1] != '_' )
1017: error('w',&m->where,"%n used but not set",m);
1018: }
1019: }
1020: }
1021: else {
1022: if (m->n_assigned_to) {
1023: }
1024: else if (m->string[0]!='_' || m->string[1]!='_') {
1025: switch (m->n_scope) {
1026: case ARG:
1027: case FCT:
1028: Cdcl = m;
1029: error('w',&m->where,"%n not used",m);
1030: }
1031: }
1032: }
1033: }
1034: }
1035: Cdcl = odcl;
1036: }
1037:
1038: d = 0;
1039:
1040: if (bit_offset) byte_offset += SZ_WORD;
1041: bit_offset = bit_old;
1042: byte_offset = byte_old;
1043: curr_block = block_old;
1044: }
1045:
1046: void name::field_align()
1047: /*
1048: adjust alignment
1049: */
1050: {
1051: Pbase fld = (Pbase)tp;
1052:
1053: int a = (F_SENSITIVE) ? fld->b_fieldtype->align() : SZ_WORD;
1054: if (max_align < a) max_align = a;
1055:
1056: if (fld->b_bits == 0) { // force word alignment
1057: int b;
1058: if (bit_offset)
1059: fld->b_bits = BI_IN_WORD - bit_offset;
1060: else if (b = byte_offset%SZ_WORD)
1061: fld->b_bits = b * BI_IN_BYTE;
1062: // else
1063: // fld->b_bits = BI_IN_WORD;
1064: if (max_align < SZ_WORD) max_align = SZ_WORD;
1065: }
1066: else if (bit_offset == 0) { // take care of part of word
1067: int b = byte_offset%SZ_WORD;
1068: if (b) {
1069: byte_offset -= b;
1070: bit_offset = b*BI_IN_BYTE;
1071: }
1072: }
1073: //error('d',"byteoff %d bitoff %d bits %d",byte_offset,bit_offset,fld->b_bits);
1074: int x = (bit_offset += fld->b_bits);
1075: if (BI_IN_WORD < x) {
1076: fld->b_offset = 0;
1077: byte_offset += SZ_WORD;
1078: bit_offset = fld->b_bits;
1079: }
1080: else {
1081: fld->b_offset = bit_offset;
1082: if (BI_IN_WORD == x) {
1083: bit_offset = 0;
1084: byte_offset += SZ_WORD;
1085: }
1086: else
1087: bit_offset = x;
1088: }
1089: n_offset = byte_offset;
1090: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.