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