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