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