|
|
1.1 root 1: /*ident "@(#)ctrans:src/expr2.c 1.1.5.29" */
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 rigths Reserved
8: THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T, INC.
9:
10: expr2.c:
11:
12: type check expressions
13:
14: ************************************************************************/
15:
16: #include "cfront.h"
17: #include "size.h"
18:
19: void name::assign()
20: {
21: if (n_assigned_to++ == 0) {
22: switch (n_scope) {
23: case FCT:
24: if (n_used && n_addr_taken==0) {
25: Ptype t = tp;
26: ll:
27: switch (t->base) {
28: case TYPE:
29: t=Pbase(t)->b_name->tp; goto ll;
30: case VEC:
31: break;
32: default:
33: if (curr_loop)
34: error('w',&where,"%n may have been used before set",this);
35: else
36: error('w',&where,"%n used before set",this);
37: }
38: }
39: }
40: }
41: }
42:
43: int ignore_const; // for use by ref_init
44: static is_dataMemPtr(Pexpr);
45:
46: int expr::lval(TOK oper)
47: {
48: register Pexpr ee = this;
49: register Pname n;
50: int deref = 0;
51: char* es;
52: char * con_idx;
53: int tpconst;
54:
55: //error('d',"%k expr::lval %k",base,oper);
56:
57: tpconst = tp->tconst ();
58: con_idx = "constant";
59:
60: switch (oper) {
61: case ADDROF:
62: case G_ADDROF: es = "address of"; break;
63: case DEREF: es = "dereference of"; break;
64: case INCR: es = "increment of"; goto def;
65: case DECR: es = "decrement of"; goto def;
66: default: es = "assignment to";
67: def:
68: if (ignore_const==0 && tpconst) {
69: tp->tconst(); /* set globals */
70: if (oper) {
71: if (base == NAME) /* can't be indexable */ {
72: if (vec_const && Pname(this)->n_scope==ARG)
73: break;
74: error("%s constant%n",es,this);
75: }
76: else
77: error("%s %s",es, con_idx);
78: }
79: return 0;
80: }
81: }
82:
83: for(;;) {
84: //error('d',"loop %k",ee->base);
85: switch (ee->base) {
86: // case G_CALL:
87: // case CALL:
88: default:
89: defa:
90: if (deref == 0) {
91: if (oper) error("%s%k (not an lvalue)",es,ee->base);
92: return 0;
93: }
94: return 1;
95: case ZERO:
96: case CCON:
97: case ICON:
98: case FCON:
99: if (oper) error("%s numeric constant",es);
100: return 0;
101: case STRING:
102: if (oper) error('w',"%s string constant",es);
103: return 1;
104: case CAST:
105: switch( oper ) {
106: case 0:
107: case ADDROF:
108: case G_ADDROF:
109: case DEREF:
110: goto defa;
111: default:
112: if ( ee->tp->base == PTR
113: && is_dataMemPtr(ee) )
114: { // check for const class object
115: /* This probable wants to be removed for the
116: same reason that the code below under DOT and REF
117: was removed -- it dosen't respect ignore_const. --benson */
118:
119: Pexpr te;
120: te = ee->e1->e1->e1;
121: if ( te->base == G_ADDROF )
122: te = te->e2;
123: if ( te->base == NAME ) {
124: Ptype pt = te->tp;
125: if ( pt->base == PTR )
126: pt = Pptr(pt)->typ;
127: if ( pt->tconst() )
128: error("%sCMP of const%n",es,te);
129: return 0;
130: }
131: }
132: goto defa;
133: }
134:
135: case DEREF:
136: {
137: Pexpr ee1 = ee->e1;
138: // error( 'd', "ee1: %k", ee1->base );
139: switch (ee1->base) { // *& vanishes
140: case ADDROF: // *&
141: return 1;
142: case G_CM:
143: case CM: // look for *(a,&b)
144: if (ee1->e2->base==G_ADDROF
145: || ee1->e2->base==ADDROF)
146: return 1;
147: goto defaa;
148: case QUEST: // look for *(q?&a:&b)
149: if ((ee1->e1->base==G_ADDROF
150: || ee1->e1->base==ADDROF)
151: && (ee1->e2->base==G_ADDROF
152: || ee1->e2->base==ADDROF))
153: return 1;
154: // no break
155: default:
156: defaa:
157: ee = ee1;
158: deref = 1;
159: }
160: break;
161: }
162:
163: case QUEST:
164: { int x1 = ee->e1->lval(deref?0:oper);
165: int x2 = ee->e2->lval(deref?0:oper);
166: if (ee->e1->tp->check(ee->e2->tp,0)) return 0;
167: if (deref) return 1;
168: return x1 && x2;
169: }
170:
171: case INCR:
172: case DECR:
173: if (e1) goto defa; // postfix does not preserve lval
174: case ASSIGN:
175: case ASPLUS:
176: case ASMINUS:
177: case ASMUL:
178: case ASDIV:
179: case ASMOD:
180: case ASAND:
181: case ASOR:
182: case ASER:
183: case ASLS:
184: case ASRS:
185: return 1;
186:
187: case CM:
188: case G_CM:
189: if (ee->e2->lval(deref?0:oper)==0) return deref;
190: return 1;
191:
192: case MEMPTR:
193: ee = ee->e2;
194: break;
195:
196: case MDOT:
197: ee = ee->mem;
198: break;
199:
200: case DOT:
201: //error('d',"dot %k oper %k",ee->e1->base,oper);
202: switch (ee->e1->base) { // update use counts, etc.
203: case NAME:
204: switch (oper) {
205: case ADDROF:
206: case G_ADDROF: Pname(ee->e1)->take_addr();
207: case 0: break;
208: case ASSIGN: Pname(ee->e1)->n_used--;
209: default: Pname(ee->e1)->assign(); // asop
210: }
211: break;
212: case DOT:
213: Pexpr e = ee->e1;
214: do e=e->e1; while (e->base==DOT);
215: if (e->base == NAME) {
216: switch (oper) {
217: case ADDROF:
218: case G_ADDROF: Pname(e)->take_addr();
219: case 0: break;
220: case ASSIGN: Pname(e)->n_used--;
221: default: Pname(e)->assign(); // asop
222: }
223: }
224: }
225:
226: n = Pname(ee->mem);
227: while (n->base == MDOT) n = Pname(Pref(n)->mem);
228:
229: #if 0
230: /* This code is no longer needed now that const is propagated up the
231: tree bottom up by expr::typ and co-conspirators. --benson
232: Since it don't respect ignore_const, it causes bizarre behavior
233: (which ought to be demonstable with the AT&T version, but
234: tends not to be because tname stripping hides consts that this
235: would find. --benson */
236: if (deref==0 && ee->e1->tp->tconst()) {
237: switch (oper) {
238: case 0:
239: case ADDROF:
240: case G_ADDROF:
241: case DEREF:
242: break;
243: default:
244: error("%sM%n of%t",es,n,ee->e1->tp);
245: }
246: return 0;
247: }
248: #endif
249: goto xx;
250:
251: case REF:
252: n = Pname(ee->mem);
253: while (n->base == MDOT) n = Pname(Pref(n)->mem);
254:
255: if (deref==0 && ee->e1) { //BR
256: Ptype p = ee->e1->tp;
257: zxc:
258: switch (p->base) {
259: case TYPE: p = Pbase(p)->b_name->tp; goto zxc;
260: case PTR:
261: case VEC: break;
262: default: error('i',"expr::lval %t->%n",p,n);
263: }
264: #if 0
265: /* This code is no longer needed now that const is propagated up the
266: tree bottom up by expr::typ and co-conspirators. --benson
267: Since it don't respect ignore_const, it causes bizarre behavior
268: (which ought to be demonstable with the AT&T version, but
269: tends not to be because tname stripping hides consts that this
270: would find. --benson */
271: if (Pptr(p)->typ->tconst()) {
272: switch (oper) {
273: case 0:
274: case ADDROF:
275: case G_ADDROF:
276: case DEREF:
277: break;
278: default:
279: error("%sM%n of%t",es,n,Pptr(p)->typ);
280: }
281: return 0;
282: }
283: #endif
284: }
285: goto xx;
286:
287: case NAME:
288: n = Pname(ee);
289: xx:
290: // error('d',"name xx: %n oper %d lex_level: %d",n,oper,n->lex_level);
291: if (deref || oper==0) return 1;
292:
293: if (n->tp->base==FIELD && Pbase(n->tp)->b_bits==0) {
294: error("%s 0-length field%n",es,n);
295: return 0;
296: }
297:
298: switch (oper) {
299: case ADDROF:
300: case G_ADDROF:
301: { Pfct f = (Pfct)n->tp;
302:
303: if (n->n_sto == REGISTER) {
304: if (warning_opt) error('w',"& register%n",n);
305: // return 0;
306: n->n_sto = 0;
307: n->n_stclass = AUTO;
308: }
309:
310: if (f == 0) {
311: error("& label%n",n);
312: return 0;
313: }
314:
315: if (n->n_stclass == ENUM) {
316: error("& enumerator%n",n);
317: return 0;
318: }
319:
320: if (n->tp->base == FIELD) {
321: error("& field%n",n);
322: return 0;
323: }
324:
325: n->n_used--;
326: if (n->n_qualifier) // oops, not the real one
327: n = Pclass(n->n_table->t_name->tp)->memtbl->look(n->string,0);
328: n->take_addr();
329:
330: // suppress hoisting of local consts
331: int statmem = n->n_scope==0 || n->n_scope==PUBLIC || n->n_scope == FCT;
332: if (n->n_evaluated && n->n_scope!=ARG) { // &const
333: n->n_evaluated = 0; // use allocated version
334: n->n_initializer = new ival(n->n_val);
335: if (statmem == 0) n->dcl_print(0);
336: }
337: else if (f->base==FCT && n->n_dcl_printed==0)
338: n->dcl_print(0);
339: break;
340: }
341:
342: case ASSIGN:
343: //error('d',"ass %n %d",n,n->n_used);
344: n->n_used--;
345: n->assign();
346: break;
347: // goto check_void;
348: default: /* incr ops, and asops */
349: if (cc->tot && n==cc->c_this) {
350: error("%n%k",n,oper);
351: return 0;
352: }
353: // check_void:
354: // { Ptype t = n->tp;
355: // while (t->base==TYPE) t = Pbase(t)->b_name->tp;
356: // if (t==Pvoid_type) {
357: // error("%s%t",es,n->tp);
358: // return 0;
359: // }
360: // }
361: n->assign();
362: }
363: return 1;
364: }
365: }
366: }
367:
368: int char_to_int(char* s)
369: /* assume s points to a string:
370: 'c'
371: or '\c'
372: or '\0'
373: or '\ddd'
374: or multi-character versions of the above
375: (hex constants have been converted to octal by the parser)
376: */
377: {
378: register int i = 0;
379: register char c, d, e;
380:
381: switch (*s) {
382: default:
383: error('i',"char constant store corrupted");
384: case '`':
385: error("bcd constant");
386: return 0;
387: case '\'':
388: break;
389: }
390:
391: for(;;) /* also handle multi-character constants */
392: switch (c = *++s) {
393: case '\'':
394: return i;
395: case '\\': /* special character */
396: switch (c = *++s) {
397: case '0': case '1': case '2': case '3': case '4':
398: case '5': case '6': case '7': /* octal representation */
399: c -= '0';
400: switch (d = *++s) { /* try for 2 */
401:
402: case '0': case '1': case '2': case '3': case '4':
403: case '5': case '6': case '7':
404: d -= '0';
405: switch (e = *++s) { /* try for 3 */
406:
407: case '0': case '1': case '2': case '3': case '4':
408: case '5': case '6': case '7':
409: c = c*64+d*8+e-'0';
410: break;
411: default:
412: c = c*8+d;
413: s--;
414: }
415: break;
416: default:
417: s--;
418: }
419: break;
420: case 'b':
421: c = '\b';
422: break;
423: case 'f':
424: c = '\f';
425: break;
426: case 'n':
427: c = '\n';
428: break;
429: case 'r':
430: c = '\r';
431: break;
432: case 't':
433: c = '\t';
434: break;
435: case '\\':
436: c = '\\';
437: break;
438: case '\'':
439: c = '\'';
440: break;
441: }
442: /* no break */
443: default:
444: if (i) i <<= BI_IN_BYTE;
445: i += c;
446: }
447: }
448:
449: const A10 = 'A'-10;
450: const a10 = 'a'-10;
451:
452: long str_to_long(register const char* p)
453: {
454: register c;
455: register unsigned long i= 0;
456: const char* pp = p;
457:
458: // error( 'd', "str_to_long: %s", p );
459:
460: if ((c=*p++) == '0') {
461: switch (c = *p++) {
462: case 0:
463: return 0;
464:
465: case 'l':
466: case 'L': /* long zero */
467: return 0;
468:
469: case 'x':
470: case 'X': /* hexadecimal */
471: while (c=*p++) {
472: switch (c) {
473: case 'l':
474: case 'L':
475: case 'U':
476: case 'u':
477: return i;
478: case 'A':
479: case 'B':
480: case 'C':
481: case 'D':
482: case 'E':
483: case 'F':
484: i = i*16 + c-A10;
485: break;
486: case 'a':
487: case 'b':
488: case 'c':
489: case 'd':
490: case 'e':
491: case 'f':
492: i = i*16 + c-a10;
493: break;
494: default:
495: i = i*16 + c-'0';
496: }
497: }
498: return i;
499:
500: default: /* octal */
501: do
502: switch (c) {
503: case 'l':
504: case 'L':
505: case 'U':
506: case 'u':
507: return i;
508: default:
509: i = i*8 + c-'0';
510: }
511: while (c=*p++);
512: return i;
513: }
514: }
515: /* decimal */
516: i = c-'0';
517: while (c=*p++)
518: switch (c) {
519: case 'l':
520: case 'L':
521: case 'U':
522: case 'u':
523: return i;
524: default:
525: { unsigned long ii = i;
526: i = i*10 + c-'0';
527: if (i<ii) goto bad;
528: }
529: }
530: return i;
531: bad:
532: error("integer constant %s larger that the largest long",pp);
533: return i;
534:
535:
536: }
537:
538: bit type::is_unsigned()
539: {
540: Ptype t = this;
541: while (t->base==TYPE) t = Pbase(t)->b_name->tp;
542: if (t->base == PTR) return 0;
543: return Pbase(t)->b_unsigned;
544: }
545:
546: char* Neval;
547: bit binary_val;
548:
549: unsigned long expr::ueval(long x1, long x2)
550: {
551: unsigned long i1 = (unsigned long) x1;
552: unsigned long i2 = (unsigned long) x2;
553: //error('d',"ueval %k %ld %ld",base,x1,x2);
554: switch (base) {
555: case UMINUS: return -i2;
556: case UPLUS: return i2;
557: case NOT: return !i2;
558: case COMPL: return ~i2;
559: case CAST: return i1;
560: case PLUS: return i1+i2;
561: case MINUS: return i1-i2;
562: case MUL: return i1*i2;
563: case LS: return i1<<i2;
564: case RS: return i1>>i2;
565: case NE: return i1!=i2;
566: case EQ: return i1==i2;
567: case LT: return i1<i2;
568: case LE: return i1<=i2;
569: case GT: return i1>i2;
570: case GE: return i1>=i2;
571: case AND: return i1&i2;
572: case ANDAND: return i1&&i2;
573: case OR: return i1|i2;
574: case OROR: return i1||i2;
575: case ER: return i1^i2;
576: case MOD: return (i2==0) ? 1 : i1%i2;
577: case QUEST: return (cond->eval()) ? i1 : i2;
578: case DIV: if (i2 == 0) {
579: if (Neval == 0) {
580: Neval = "divide by zero";
581: error('w',"divide by zero");
582: }
583: return 1;
584: }
585: return i1/i2;
586: case CM:
587: case G_CM:
588: return i2;
589: }
590:
591: Neval = "unsigned expression";
592: return 0;
593: }
594:
595: long expr::eval()
596: {
597: static long cast_mask[] = { 0377, 0177777, 077777777, ~0 };
598:
599: if (Neval) return 1;
600: // error('d',"eval %k",base);
601:
602: switch (base) {
603: case ZERO: return 0;
604: case IVAL: return i1;
605: case ICON: return str_to_long(string);
606: case CCON: return char_to_int(string);
607: case FCON: Neval = "float in constant expression"; return 1;
608: case STRING: Neval = "string in constant expression"; return 1;
609: case EOBJ: return Pname(this)->n_val;
610: case SIZEOF:
611: extern no_sizeof;
612: if (no_sizeof) Neval = "sizeof";
613: return tp2->tsizeof();
614:
615: case NAME:
616: { Pname n = Pname(this);
617: // error('d',"eval %n eval %d %d",n,n->n_evaluated,n->n_val);
618: // error('d',"eval tp->tconst() %d, n->n_initializer: %k", n->tp->tconst(), n->n_initializer?n->n_initializer->base:0 );
619: if (n->n_evaluated && n->n_scope!=ARG) return n->n_val;
620: if (n->n_initializer
621: && n->n_scope!=ARG
622: && n->n_initializer->base==IVAL // encoding for outlined
623: && n->n_initializer->i1==n->n_val // const see ::lval above
624: && n->tp->tconst()) return n->n_val;
625: if (binary_val && strcmp(string,"_result")==0) return 8888;
626: Neval = "cannot evaluate constant";
627: return 1;
628: }
629: case ICALL:
630: if (e1) {
631: il->i_next = curr_icall;
632: curr_icall = il;
633: long i = e1->eval();
634: curr_icall = il->i_next;
635: return i;
636: }
637: Neval = "void inlineF";
638: return 1;
639: case ANAME:
640: { Pname n = (Pname)this;
641: int argno = (int)n->n_val;
642: Pin il;
643: for (il=curr_icall; il; il=il->i_next)
644: if (il->i_table == n->n_table) goto aok;
645: goto bok;
646: aok:
647: if (il->i_args[argno].local) {
648: bok:
649: Neval = "inlineF call too complicated for constant expression";
650: return 1;
651: }
652: Pexpr aa = il->i_args[argno].arg;
653: return aa->eval();
654: }
655: case CAST:
656: { if (e1->base == FCON) {
657: char* p = e1->string;
658: while (*p!='.') p++;
659: if (p==e1->string) *p++ = '0';
660: *p = 0;
661: e1->base = ICON;
662: }
663: long i = e1->eval();
664: Ptype tt = tp2;
665: strip:
666: switch (tt->base) {
667: default:
668: Neval = "cast to non-integral type in constant expression";
669: break;
670: case TYPE:
671: tt = Pbase(tt)->b_name->tp;
672: goto strip;
673: case EOBJ:
674: case LONG:
675: case INT:
676: case CHAR:
677: case SHORT:
678: {
679: if (BI_IN_BYTE!=8) error('i',"expr::eval() assumes 8 bit bytes, please re-write it");
680: if (4<SZ_LONG) error('i',"expr::eval() assumes sizeof(long)<=4, please re-write it");
681: i &= cast_mask[tp2->tsizeof()-1];
682: }
683: }
684: return i;
685: }
686: case UMINUS:
687: case UPLUS:
688: case NOT:
689: case COMPL:
690: case PLUS:
691: case MINUS:
692: case MUL:
693: case LS:
694: case RS:
695: case NE:
696: case LT:
697: case LE:
698: case GT:
699: case GE:
700: case AND:
701: case OR:
702: case ER:
703: case DIV:
704: case MOD:
705: case QUEST:
706: case EQ:
707: case ANDAND:
708: break;
709: case OROR:
710: if (binary_val) { // a||b, don't evaluate b if a!=0
711: long i1 = (e1) ? e1->eval() : 0;
712: if (Neval==0 && i1 && e1->tp->is_unsigned()==0) return i1;
713: }
714: break;
715: case CM:
716: case G_CM:
717: break;
718: case G_ADDROF:
719: case ADDROF:
720: if (binary_val) { // beware of &*(T*)0
721: switch (e2->base) {
722: case NAME:
723: case DOT:
724: case REF: return 9999;
725: }
726: }
727: default:
728: Neval = "bad operator in constant expression";
729: return 1;
730: }
731:
732: long i1 = (e1) ? e1->eval() : 0;
733: long i2 = (e2) ? e2->eval() : 0;
734:
735: if (binary_val && i1==9999 && i2==9999) {
736: Neval = "";
737: return 1;
738: }
739:
740: if (Neval==0
741: && ((e1&&e1->tp->is_unsigned()) || (e2&&e2->tp->is_unsigned())))
742: return (long) ueval(i1,i2);
743:
744: switch (base) {
745: case UMINUS: return -i2;
746: case UPLUS: return i2;
747: case NOT: return !i2;
748: case COMPL: return ~i2;
749: case CAST: return i1;
750: case PLUS: return i1+i2;
751: case MINUS: return i1-i2;
752: case MUL: return i1*i2;
753: case LS: return i1<<i2;
754: case RS: return i1>>i2;
755: case NE: return i1!=i2;
756: case EQ: return i1==i2;
757: case LT: return i1<i2;
758: case LE: return i1<=i2;
759: case GT: return i1>i2;
760: case GE: return i1>=i2;
761: case AND: return i1&i2;
762: case ANDAND: return i1&&i2;
763: case OR: return i1|i2;
764: case OROR: return i1||i2;
765: case ER: return i1^i2;
766: case MOD: return (i2==0) ? 1 : i1%i2;
767: case QUEST: return (cond->eval()) ? i1 : i2;
768: case DIV: if (i2 == 0) {
769: if (Neval == 0) {
770: Neval = "divide by zero";
771: error('w',"divide by zero");
772: }
773: return 1;
774: }
775: return i1/i2;
776: case CM:
777: case G_CM:
778: return i2;
779: }
780: }
781: extern TOK ppbase;
782: bit classdef::baseof(Pname f)
783: /*
784: is ``this'' class a public base class of "f"'s class
785: or its immediate base class
786: */
787: {
788: Ptable ctbl = f->n_table;
789: Pname b = ctbl->t_name;
790:
791: if (b == 0) return 0;
792: Pclass cl = Pclass(b->tp);
793: if (cl == 0) return 0;
794: if (cl == this) return 1;
795: ppbase = PUBLIC;
796: Pclass bcl = is_base(cl->string);
797: return (bcl && ppbase==PUBLIC);
798: }
799:
800: bit classdef::baseof(Pclass cl)
801: /*
802: is ``this'' class a public base class of "cl"
803: */
804: {
805: if (cl == 0) return 0;
806: if (cl == this) return 1;
807: ppbase = PUBLIC;
808: Pclass bcl = is_base(cl->string);
809: return (bcl && ppbase==PUBLIC);
810: }
811:
812: static int mem_match(Pfct f1, Pfct f2)
813: /*
814: check class membership.
815:
816: For some reason checking f_this==0 works and f_static doesn't
817: */
818: {
819: // if (f1->memof) return f2->f_this ?f2->memof==f1->memof : 0;
820: // if (f1 && f1->memof) return f2->f_this?f2->memof==f1->memof : 0;
821: // return f2->f_this==0;
822: if (f1==0 || f2==0) return 0;
823: if (f1->memof && f2->f_this && f2->memof!=f1->memof) return 0;
824: if (f2->f_this) return 0;
825: if (f1->check(f2,ASSIGN)) return 0;
826: return 1;
827: }
828:
829: int Pchecked;
830:
831: Pexpr ptof(Pfct ef, Pexpr e, Ptable tbl)
832: /*
833: a kludge: initialize/assign-to pointer to function
834: */
835: {
836: Pfct f;
837: Pname n = 0;
838: eee:
839: //error('d',"ptof %t %t %k",ef,e->tp,e->base);
840: switch (e->base) {
841: case QUEST:
842: e->e1 = ptof(ef,e->e1,tbl);
843: e->e2 = ptof(ef,e->e2,tbl);
844: return e;
845: case CM:
846: case G_CM:
847: e->e2 = ptof(ef,e->e2,tbl);
848: return e;
849: case NAME:
850: f = Pfct(e->tp);
851: // n = Pname(e);
852:
853: switch (f->base) {
854: case OVERLOAD:
855: e = Pgen(f)->find(ef,0);
856: if (e == 0) error("cannot deduceT for &overloaded%n",e);
857: // e = n;
858: // no break
859: case FCT:
860: Pchecked = mem_match(ef,Pfct(e->tp));
861: e = new expr(G_ADDROF,0,e);
862: return e->typ(tbl); // handle &B::f
863: //e->tp = f;
864: }
865: goto ad;
866:
867: case ZERO:
868: if (ef->memof) {
869: e = new expr(ELIST,zero,zero);
870: e = new expr(ILIST,e,zero);
871: e->tp = zero_type;
872: return e;
873: }
874: break;
875:
876: case MDOT:
877: error('s',"P toM of not firstB");
878: do e = e->mem; while (e->base == MDOT);
879: goto eee;
880:
881: case DOT:
882: case REF:
883: f = Pfct(e->mem->tp);
884:
885: switch (f->base) {
886: case OVERLOAD:
887: e = Pgen(f)->find(ef,0);
888: if (n == 0) error("cannot deduceT for &overloaded%n",e->mem);
889: // e->mem = n;
890: // no break
891: case FCT:
892: Pchecked = mem_match(ef,Pfct(e->tp));
893: e = new expr(G_ADDROF,0,e);
894: return e->typ(tbl); // handle &B::f
895: // n = Pname(e->mem);
896: // e = n->address();
897: }
898: goto ad;
899:
900: case ADDROF:
901: case G_ADDROF:
902: f = Pfct(e->e2->tp);
903: ad:
904: if (f->base == OVERLOAD) {
905: n = Pgen(f)->find(ef,0);
906: if (n == 0) error("cannot deduceT for &overloaded %s()",Pgen(f)->fct_list->f->string);
907: Pchecked = mem_match(ef,Pfct(n->tp));
908: e->e2 = n;
909: e->tp = n->tp;
910: }
911: if (n) n->lval(ADDROF);
912: break;
913:
914: case CAST:
915: {
916: Pexpr te = e->e1;
917: if (e->e1->base == G_ADDROF) te = e->e1->e2;
918: (void) ptof(ef,te,tbl);
919: }
920: }
921: return e;
922: }
923:
924: Pexpr ptr_init(Pptr p, Pexpr init, Ptable tbl)
925: /*
926: check for silly initializers
927:
928: char* p = 0L; ?? fudge to allow redundant and incorrect `L'
929: char* p = 2 - 2; ?? worse
930: */
931: {
932: //error('d',"ptr_init: p=%t init->tp=%t init->base %k",p,init->tp,init->base);
933:
934: Pchecked = 0;
935:
936: Ptype it = init->tp;
937: itl:
938: switch (it->base) {
939: case TYPE:
940: it = Pbase(it)->b_name->tp; goto itl;
941: case ZTYPE:
942: // if (init == zero) break;
943: break;
944: case EOBJ:
945: case INT:
946: case CHAR:
947: case SHORT:
948: { Neval = 0;
949: long i = init->eval();
950: if (Neval)
951: error("badPIr: %s",Neval);
952: else
953: if (i)
954: error("badPIr value %d",i);
955: else {
956: DEL(init);
957: init = zero;
958: }
959: break;
960: }
961: case LONG:
962: if (init->base==ICON
963: && init->string[0]=='0'
964: && (init->string[1]=='L' || init->string[1]=='l')) {
965: DEL(init);
966: init = zero;
967: }
968: break;
969: }
970:
971: Pclass c1 = p->memof;
972:
973: if (c1) {
974: //error('d',"c1 %t",c1);
975: if (init==zero)
976: ;
977: else {
978: Pclass c2;
979: //error('d',"it %t %d",it,it->base);
980: switch (it->base) {
981: case FCT:
982: c2 = Pfct(it)->memof;
983: break;
984: case OVERLOAD:
985: c2 = Pfct(Pgen(it)->fct_list->f->tp)->memof;
986: break;
987: case PTR:
988: case RPTR:
989: c2 = Pptr(it)->memof;
990: break;
991: default:
992: c2 = 0;
993: }
994:
995: if (c2 == 0) {
996: // initialization by &A::f
997: //error('d',"curious");
998: }
999: else if (c1 != c2) {
1000: Nptr = 0;
1001: Noffset = 0;
1002: vcllist->clear();
1003: vcllist=0;
1004: int u1 = is_unique_base(c1,c2->string,0);
1005: //error('d',"c1 %t c2 %t u1 %d off %d",c1,c2,u1,Noffset);
1006: if (u1 && (Nptr || Noffset)) {
1007: // requires offset manipulation
1008: int bad = 0;
1009: if (u1 == 1 && !Nptr) {
1010: //error('d',"try c1 %t c2 %t u1 %d off %d",c1,c2,u1,Noffset);
1011: //error('d',"init %k %t",init->base,init->tp);
1012: if (init->base==ILIST) {
1013: // d = d+Noffset;
1014: //error('d'," d %k %d",init->e1->e1->base,init->e1->e1->i1);
1015: switch (init->e1->e1->base) {
1016: case IVAL:
1017: init->e1->e1->i1 += Noffset;
1018: break;
1019: case ZERO:
1020: init->e1->e1 = new ival(Noffset);
1021: break;
1022: default:
1023: bad = 1;
1024: }
1025:
1026: //error('d'," i %k %d",init->e1->e2->base,init->e1->e2->i1);
1027: // if (i<0) f = vptroffset
1028: switch (init->e1->e2->base) {
1029: case IVAL:
1030: if (0<init->e1->e2->i1) {
1031: //error('d',"vptr");
1032: extern Ptype Pfct_type;
1033: // store vptr offset
1034: // init->e2 = new cast(Pfct_type,zero);
1035: }
1036: else
1037: break;
1038: default:
1039: bad = 1;
1040: }
1041: }
1042: else
1043: bad = 1;
1044:
1045: }
1046: else
1047: bad = 1;
1048:
1049: if (bad) error('s',"%t assigned to %t (too complicated)",init->tp,p);
1050: }
1051:
1052: Nptr = 0;
1053: Noffset = 0;
1054: vcllist->clear();
1055: vcllist=0;
1056: int u2 = is_unique_base(c2,c1->string,0);
1057: //error('d',"c1 %t c2 %t u2 %d off %d",c1,c2,u2,Noffset);
1058: if (u2 && (Nptr || Noffset)) {
1059: // requires offset manipulation
1060: error('s',"%t assigned to %t",init->tp,p);
1061: }
1062: }
1063: }
1064: }
1065:
1066: Ptype pit = p->typ;
1067: lll:
1068: //error('d',"p %t pit %t",p,pit);
1069: switch (pit->base) {
1070: case TYPE:
1071: pit = Pbase(pit)->b_name->tp;
1072: goto lll;
1073: case FCT:
1074: return ptof(Pfct(pit),init,tbl);
1075: case COBJ:
1076: { Pptr r;
1077: //error('d',"cobj: ptr %t, ref %t",it->is_ptr(),it->is_ref());
1078: if (r=it->is_ptr_or_ref()) {
1079: Pchecked = 1;
1080: TOK b = p->base; // could be REF
1081: TOK bb = r->base;
1082: if (b==RPTR) p->base = PTR;
1083: if (bb==RPTR) r->base = PTR;
1084: if (p->check(r,ASSIGN))
1085: error("no standard conversion of %t to %t",init->tp,p);
1086: p->base = b;
1087: r->base = bb;
1088: Pexpr cp = cast_cptr(Pclass(Pbase(pit)->b_name->tp),init,tbl,0);
1089: if (cp != init) {
1090: PERM(p); // or else it will be deleted twice!
1091: return new cast(p,cp);
1092: }
1093: }
1094: // no break
1095: }
1096: default:
1097: return init;
1098: }
1099: }
1100:
1101: static Pname Lcoerce, Rcoerce;
1102: extern int suppress_error;
1103:
1104: int try_to_demote(TOK oper, Ptype t1, Ptype t2)
1105: /*
1106: look at t1 and t2 and see if there are ``demotions'' of t1 and/or t2
1107: so that ``t1 oper t2'' can be made legal
1108:
1109: return 0 is not
1110: 1 if there is exactly one way
1111: >1 if there is more than one way (if in doubt return 2)
1112: */
1113: {
1114: //error('d',"try_to_demote(%k : %t : %t)",oper,t1,t2);
1115:
1116: Pname n1 = t1 ? t1->is_cl_obj() : 0;
1117: Pclass c1 = n1 ? Pclass(n1->tp) : 0;
1118: Pname n2 = t2 ? t2->is_cl_obj() : 0;
1119: Pclass c2 = n2 ? Pclass(n2->tp) : 0;
1120:
1121: Ptype lt = t1;
1122: Ptype rt = t2;
1123:
1124: Lcoerce = Rcoerce = 0;
1125:
1126: // if (oper == DOT) return 0;
1127:
1128: if (c1)
1129: switch (oper) {
1130: case ASSIGN:
1131: case ASPLUS:
1132: case ASMINUS:
1133: case ASMUL:
1134: case ASDIV:
1135: case ASMOD:
1136: case ASAND:
1137: case ASOR:
1138: case ASER:
1139: case ASLS:
1140: case ASRS: // don't coerce left hand side of assignment
1141: // c1 = 0;
1142: if (c1->memtbl->look("__as",0)) return 0;
1143: }
1144: else
1145: switch (oper) {
1146: case ADDROF:
1147: case INCR:
1148: case DECR: // don't coerce unary requiring an lval
1149: return 0;
1150: }
1151:
1152: if (c1) {
1153: //error('d',"c1 %t",c1);
1154: for (Pname on1 = c1->conv; on1; on1=on1->n_list) {
1155: Pfct f = Pfct(on1->tp);
1156: lt = f->returns;
1157: Pname cn = lt->is_cl_obj();
1158:
1159: if (cn && (Lcoerce==0 || Lcoerce->tp->check(f,0))) {
1160: Pclass cl = Pclass(cn->tp);
1161: Pname n = cl->has_oper(oper);
1162: if (n == 0) continue;
1163: // while (n->base==REF || n->base==MDOT) n=Pname(n->mem);
1164: Pfct nf = Pfct(n->tp);
1165: if (nf->base == FCT) {
1166: if (nf->nargs==1
1167: && (nf->argtype->tp->check(t2,ARG)==0
1168: || can_coerce(nf->argtype->tp,t2)==1)
1169: ) {
1170: if (Lcoerce) return 2;
1171: Lcoerce = on1;
1172: }
1173: }
1174: else {
1175: for (Plist gl=Pgen(nf)->fct_list; gl; gl=gl->l) {
1176: Pfct nf = Pfct(gl->f->tp);
1177: if (nf->nargs==1
1178: && (nf->argtype->tp->check(t2,ARG)==0
1179: || can_coerce(nf->argtype->tp,t2)==1)
1180: ) {
1181: if (Lcoerce) return 2;
1182: Lcoerce = on1;
1183: }
1184: }
1185: }
1186: continue;
1187: }
1188: //if (lt->is_cl_obj()) continue;
1189: if (c2) {
1190: //error('d',"c2 %t",c2);
1191: for (Pname on2 = c2->conv; on2; on2=on2->n_list) {
1192: Pfct f = Pfct(on2->tp);
1193: rt = f->returns;
1194: if (rt->is_cl_obj()) continue;
1195:
1196: suppress_error = 1;
1197: int r1 = lt->kind(oper,0);
1198: int r2 = rt->kind(oper,0);
1199: if (np_promote(oper,r1,r2,lt,rt,1)!=any_type) {
1200: if (Lcoerce) {
1201: suppress_error = 0;
1202: return 2;
1203: }
1204: Lcoerce = on1;
1205: Rcoerce = on2;
1206:
1207: };
1208: suppress_error = 0;
1209: }
1210:
1211: }
1212: else if (rt) {
1213: suppress_error = 1;
1214: int r1 = lt->kind(oper,0);
1215: int r2 = rt->kind(oper,0);
1216: if (np_promote(oper,r1,r2,lt,rt,1)!=any_type) {
1217: if (Lcoerce) {
1218: suppress_error = 0;
1219: return 2;
1220: }
1221: Lcoerce = on1;
1222: };
1223: suppress_error = 0;
1224: }
1225: else {
1226: if (Lcoerce) return 2;
1227: Lcoerce = on1;
1228: }
1229: }
1230: }
1231: else if (c2) {
1232: //error('d',"c2 %n",c2);
1233: for (Pname on = c2->conv; on; on=on->n_list) {
1234: Pfct f = Pfct(on->tp);
1235: rt = f->returns;
1236: Pname cn = rt->is_cl_obj();
1237: //error('d',"cn %n",cn);
1238: if (cn && (Rcoerce==0 || Rcoerce->tp->check(f,0))) {
1239: Pclass cl = Pclass(cn->tp);
1240: Pname n = cl->has_oper(oper);
1241: if (n == 0) continue;
1242:
1243: // while (n->base==REF || n->base==MDOT) n=Pname(n->mem);
1244: Pfct nf = Pfct(n->tp);
1245: if (nf->base == FCT) {
1246: if (nf->nargs == 0) {
1247: if (Lcoerce || Rcoerce) return 2;
1248: Rcoerce = on;
1249: }
1250: }
1251: else {
1252: for (Plist gl=Pgen(nf)->fct_list; gl; gl=gl->l)
1253: if (Pfct(gl->f->tp)->nargs == 0) {
1254: if (Lcoerce || Rcoerce) return 2;
1255: Rcoerce = on;
1256: }
1257: }
1258: continue;
1259: }
1260: //if (rt->is_cl_obj()) continue;
1261: suppress_error = 1;
1262: int r1 = lt->kind(oper,0);
1263: int r2 = rt->kind(oper,0);
1264:
1265: if (np_promote(oper,r1,r2,lt,rt,1)!=any_type) {
1266: if (Lcoerce || Rcoerce) {
1267: suppress_error = 0;
1268: return 2;
1269: }
1270: Rcoerce = on;
1271: }
1272: suppress_error = 0;
1273: }
1274: }
1275:
1276: //error('d',"->%d || %d",Lcoerce,Rcoerce);
1277: return (Lcoerce || Rcoerce);
1278: }
1279:
1280: Pexpr expr::try_to_overload(Ptable tbl)
1281: {
1282: // TOK bb = (base==DEREF && e2==0) ? MUL : base;
1283: //error('d',"try_to_overload %k %k",base,base);
1284:
1285: Pname n1 = 0;
1286: Ptype t1 = 0;
1287:
1288: if (e1) {
1289: t1 = e1->tp;
1290: Ptype tpx = t1;
1291: while (tpx->base == TYPE) tpx = Pbase(tpx)->b_name->tp;
1292: n1 = tpx->is_cl_obj();
1293: }
1294:
1295:
1296: TOK bb = base;
1297: switch (bb) {
1298: case DEREF:
1299: if (e2 == 0) bb = MUL;
1300: // no break;
1301: case CALL:
1302: case G_CALL:
1303: if (n1 == 0) return 0; // ignore type of argument list
1304: }
1305:
1306: Pname n2 = 0;
1307: Ptype t2 = 0;
1308:
1309: if (e2 && e2->base!=ELIST) {
1310: t2 = e2->tp;
1311: Ptype tpx = t2;
1312: while (tpx->base == TYPE) tpx = Pbase(tpx)->b_name->tp;
1313: n2 = tpx->is_cl_obj();
1314: }
1315:
1316: if (n1==0 && n2==0) return 0;
1317: if (n1 && n1->tp == 0) return 0; // make_assign() fudge
1318: //error('d',"t1 %t t2 %t",t1,t2);
1319: //error('d',"n1 %n n2 %n",n1,n2);
1320: /* first try for non-member function: op(e1,e2) or op(e2) or op(e1) */
1321: Pexpr oe2 = e2;
1322: Pexpr ee2 = (e2 && e2->base!=ELIST) ? e2 = new expr(ELIST,e2,0) : 0;
1323: Pexpr ee1 = e1 ? new expr(ELIST,e1,e2) : ee2;
1324: char* obb = oper_name(bb);
1325: Pname gname = gtbl->look(obb,0);// first look at member functions
1326: // then if necessary check for ambiguities
1327: int go = gname ? over_call(gname,ee1) : 0;
1328: //error('d',"go %d",go);
1329: if (go) gname = Nover;
1330:
1331: if (n1) {
1332: if (bb == ASSIGN) {
1333: Pclass c1 = Pclass(n1->tp);
1334: //error('d',"look %k %d",bb,c1->memtbl->look(obb,0));
1335: if (c1->memtbl->look(obb,0)==0) {
1336: Pclass bcl = c1->baselist?c1->baselist->bclass:0;
1337: if (n2==0
1338: || (Pclass(n2->tp)!=c1
1339: && Pclass(n2->tp)->has_base(c1)==0)) {
1340: // if legal, a=1 can be optimized to a.ctor(1)
1341: if (2 < go) goto glob;
1342: return 0;
1343: }
1344:
1345: if (bcl
1346: && c1->obj_size!=bcl->obj_size
1347: && bcl->memtbl->look(obb,0)) {
1348: // cannot inherit from smaller base class
1349: // make_assignment(n1);
1350: // return try_to_overload(tbl);
1351: goto mkas;
1352: }
1353:
1354: if (c1->c_xref&(C_VBASE|C_VPTR|C_ASS)) {
1355: // make operator=() if
1356: // no base (shouldn't happen
1357: // different (smaller) sized base
1358: // two bases
1359: mkas:
1360: if (2 < go) goto glob;
1361: // make_assignment(n1);
1362: // return try_to_overload(tbl);
1363: return make_assignment(n1) ? try_to_overload(tbl) : 0;
1364: }
1365: //error('d',"n2 %n",n2);
1366: // if (n2 && Pclass(n2->tp)==c1)
1367: return 0;
1368: }
1369: // now take care of other assignments,
1370: }
1371:
1372: Pexpr mn = Pclass(n1->tp)->find_name(obb,0);
1373: Pname mname = Pname(mn);
1374: //error('d',"mn %n %d %k %s",mname,mn,mn?mn->base:0,obb);
1375: if (mname == 0) goto glob;
1376:
1377: zaq:
1378: switch (mname->base) {
1379: case REF:
1380: case MDOT:
1381: mname = Pname(Pexpr(mname)->mem);
1382: goto zaq;
1383: }
1384:
1385: int mo = over_call(mname,e2);
1386: //error('d',"mo %d (go %d)",mo,go);
1387: if (mo==0 || mo<go)
1388: goto glob;
1389: else if (mo && mo==go) {
1390: //error('d',"t1 %t t2 %t",t1,t2);
1391: if (gname->tp->base == OVERLOAD) { // find right version
1392: for (Plist l = Pgen(gname->tp)->fct_list; l; l=l->l) {
1393: Pname n = l->f;
1394: int x = over_call(n,ee1);
1395: if (x == go) {
1396: gname = n;
1397: break;
1398: }
1399: }
1400: }
1401: //error('d',"gname %n: %t",gname,gname->tp);
1402: Pname aa = Pfct(gname->tp)->argtype;
1403: Pptr p;
1404: Ptype gt1 = aa->tp;
1405: if (p = gt1->is_ref()) gt1 = p->typ;
1406: Ptype gt2 = aa->n_list->tp;
1407: //error('d',"gt1 %t gt2 %t",gt1,gt2);
1408: if (mname->tp->base == OVERLOAD) { // find right version
1409: for (Plist l = Pgen(mname->tp)->fct_list; l; l=l->l) {
1410: Pname n = l->f;
1411: int x = over_call(n,e2);
1412: if (x == mo) {
1413: mname = n;
1414: break;
1415: }
1416: }
1417: }
1418: //error('d',"mname %n: %t",mname,mname->tp);
1419: Ptype mt1 = Pfct(mname->tp)->f_this->tp;
1420: mt1 = Pptr(mt1)->typ;
1421: Ptype mt2 = Pfct(mname->tp)->argtype->tp;
1422: //error('d',"mt1 %t mt2 %t",mt1,mt2);
1423: Pname mm = new name;
1424: Pname a1 = new name;
1425: a1->tp = mt1;
1426: Pname a2 = new name;
1427: a2->tp = mt2;
1428: a1->n_list = a2;
1429: mm->tp = new fct(void_type,a1,2);
1430: Pname gg = new name;
1431: Pname a3 = new name;
1432: a3->tp = gt1;
1433: Pname a4 = new name;
1434: a4->tp = gt2;
1435: a3->n_list = a4;
1436: gg->tp = new fct(void_type,a3,1);
1437: extern Pname dominate(Pname,Pname,Pexpr,int,int);
1438: aa = dominate(gg,mm,ee1,0,1);
1439: delete a1;
1440: delete a2;
1441: delete a3;
1442: delete a4;
1443: delete gg->tp;
1444: delete mm->tp;
1445: if (aa == 0) {
1446: delete gg;
1447: delete mm;
1448: error("ambiguous operandTs%n and%t for%k",n1,t2,bb);
1449: tp = any_type;
1450: return this;
1451: }
1452: else if (aa == gg) {
1453: delete gg;
1454: delete mm;
1455: goto glob;
1456: }
1457: delete gg;
1458: delete mm;
1459: }
1460: else if (mo < 2) { // user-defined conversion user
1461: if (try_to_demote(bb,t1,t2))
1462: error("ambiguous use of overloaded%k",bb);
1463: }
1464:
1465: base = G_CALL; // e1.op(e2) or e1.op()
1466: Pname xx = new name(mname->string); // do another lookup
1467: // . suppresses virtual
1468: e1 = new ref(DOT,e1,xx);
1469: if (ee1) delete ee1;
1470: return typ(tbl);
1471: }
1472:
1473: if (n2 && e1==0) { /* look for unary operator */
1474: Pexpr mn = Pclass(n2->tp)->find_name(obb,0);
1475: Pname mname = Pname(mn);
1476: if (mname == 0) goto glob;
1477: zaqq:
1478: switch (mname->base) {
1479: case REF:
1480: case MDOT:
1481: mname = Pname(Pexpr(mname)->mem);
1482: goto zaqq;
1483: }
1484:
1485: switch (mname->n_scope) {
1486: default: goto glob;
1487: case 0:
1488: case PUBLIC: break; // try e2.op()
1489: }
1490:
1491: int mo = over_call(mname,0);
1492: //error('d',"e2 mo %d (go %d)",mo,go);
1493: if (mo==0 || mo<go)
1494: goto glob;
1495: else if (mo==go) {
1496: error("ambiguous operandT%n for%k",n2,bb);
1497: tp = any_type;
1498: return this;
1499: }
1500: else if (mo < 2) { // user-defined conversion user
1501: if (try_to_demote(bb,t1,t2))
1502: error("ambiguous use of overloaded%k",bb);
1503: }
1504: base = G_CALL; // e2.op()
1505: Pname xx = new name(Nover->string); // do another lookup
1506: // . suppresses virtual
1507: e1 = new ref(DOT,oe2,xx);
1508: e2 = 0;
1509: if (ee2) delete ee2;
1510: if (ee1 && ee1!=ee2) delete ee1;
1511: return typ(tbl);
1512: }
1513:
1514: glob:
1515: //error('d',"glob %d",go);
1516:
1517: if (go) {
1518: if (go < 2) { // user-defined conversion necessary => binary
1519: if (try_to_demote(bb,t1,t2))
1520: error("ambiguous use of overloaded%k: %t and %t",bb,t1,t2);
1521: }
1522:
1523: base = G_CALL; // ::op(e1,e2) or ::op(e1) or ::op(e2)
1524: //error('d',"gname %n %t",gname,gname->tp);
1525: e1 = new name(gname->string);
1526: Pname(e1)->n_qualifier = sta_name; // look only for globals
1527: e2 = ee1;
1528: return typ(tbl);
1529: }
1530:
1531: if (ee2) delete ee2;
1532: if (ee1 && ee1!=ee2) delete ee1;
1533: e2 = oe2;
1534:
1535: //error('d',"bb %d %k",bb,bb);
1536: switch (bb) {
1537: case CM:
1538: case G_CM:
1539: case G_ADDROF:
1540: return 0;
1541: case ASSIGN:
1542: if (n1
1543: && n2
1544: && (n1->tp==n2->tp || Pclass(n2->tp)->has_base(Pclass(n1->tp)))) {
1545: if (make_assignment(n1))
1546: return try_to_overload(tbl);
1547: else
1548: return 0;
1549: }
1550: case DEREF:
1551: case CALL:
1552: if (n1 == 0) break;
1553:
1554: default: /* look for conversions to basic types */
1555: if (n1
1556: && Pclass(n1->tp)->conv
1557: && (bb==ANDAND || bb==OROR)) {
1558: e1 = check_cond(e1,bb,tbl);
1559: return 0;
1560: }
1561:
1562: if (n2
1563: && Pclass(n2->tp)->conv
1564: && (bb==ANDAND || bb==OROR || bb==NOT)) {
1565: e2 = check_cond(e2,bb,tbl);
1566: return 0;
1567: }
1568:
1569: switch (try_to_demote(bb,t1,t2)) {
1570: default:
1571: if (Lcoerce) error("ambiguous conversion of%n",n1);
1572: if (Rcoerce) error("ambiguous conversion of%n",n2);
1573: case 0:
1574: break;
1575: case 1:
1576: if (Lcoerce) {
1577:
1578: Pname xx = new name(Lcoerce->string);
1579: Pref r = new ref(DOT,e1,xx);
1580: e1 = new expr(G_CALL,r,0);
1581: }
1582:
1583: if (Rcoerce) {
1584:
1585: Pname xx = new name(Rcoerce->string);
1586: Pref r = new ref(DOT,e2,xx);
1587: e2 = new expr(G_CALL,r,0);
1588: }
1589: return typ(tbl);
1590: }
1591:
1592: switch (bb) {
1593: case CM:
1594: case ADDROF: // has legal built-in meaning
1595: return 0;
1596: }
1597:
1598: if (t1 && t2)
1599: error("bad operandTs%t%t for%k",t1,t2,bb);
1600: else
1601: error("bad operandT%t for%k",t1?t1:t2,bb);
1602:
1603: tp = any_type;
1604: return this;
1605: }
1606:
1607: return 0;
1608: }
1609:
1610: Pexpr cast_cptr(Pclass ccl, Pexpr ee, Ptable tbl, int real_cast)
1611: /*
1612: "ee" is being cast to pointer object of class "ccl"
1613: if necessary modify "ee"
1614: */
1615: {
1616:
1617: // Ptype etp = ee->tp;
1618: //error('d',"cast_cptr %k ccl %t ee->tp %t",ee->tp->base,ccl,ee->tp);
1619:
1620: // if (etp->base!=PTR && etp->base!=RPTR) return ee;
1621: Ptype etp = ee->tp->is_ptr_or_ref();
1622: if (etp == 0) return ee;
1623:
1624: Pname on = Pptr(etp)->typ->is_cl_obj();
1625: if (on == 0) return ee;
1626:
1627: Pclass ocl = Pclass(on->tp);
1628: if (ocl==ccl || ccl==0 || ocl==0) return ee;
1629:
1630: //error('d',"cast_cptr %t(%t) real %d",ccl,ocl,real_cast);
1631: int oo = 0;
1632: Pexpr r = 0;
1633:
1634: if (ocl->baselist
1635: && (ocl->baselist->bclass!=ccl || ocl->baselist->base!=NAME)) {
1636: // casting derived to second or virtual base?
1637: Nptr = 0;
1638: vcllist->clear();
1639: vcllist=0;
1640: int x = is_unique_base(ocl,ccl->string,0);
1641: //error('d',"x1 %d",x);
1642: if (Nvis) {
1643: if (real_cast==0)
1644: error("cast:%n* ->B%t*; privateBC",on,ccl);
1645: else if (warning_opt)
1646: error('w',"cast:%n* ->B%t*; privateBC",on,ccl);
1647: real_cast = 1; // suppress further error mesages
1648: Nvis = 0;
1649: }
1650:
1651: switch (x) {
1652: default:
1653: error("cast:%n* ->B%t*;%t isB more than once",on,ccl,ccl);
1654: case 0: // unrelated;
1655: break;
1656: case 1:
1657: oo = Noffset;
1658: break;
1659: }
1660:
1661: if (Nptr) { // => ee?Nptr:0
1662: //error('d',"nptr");
1663: if (ocl->c_body==1) ocl->dcl_print(0);
1664: Nptr->mem = ee; // ee->Pbase_class
1665: Nptr->i1 = 3;
1666: if (ee->base==ADDROF || ee->base==G_ADDROF)
1667: ee = Nptr;
1668: else {
1669: Pexpr p = new expr(QUEST,Nptr,zero);
1670: extern nin;
1671: nin = 1;
1672: if (ee->not_simple()) { // need temp
1673: Ptype t = ee->tp;
1674: Pname pp = make_tmp('N',t,tbl);
1675: Pname(pp)->n_assigned_to = 1;
1676: ee = new expr(ASSIGN,pp,ee);
1677: ee->tp = t;
1678: Nptr->mem = pp;
1679: }
1680: nin = 0;
1681: p->cond = ee;
1682: //error('d',"p->tp %t",ee->tp);
1683: p->tp = ee->tp;
1684: ee = p;
1685: }
1686: }
1687: }
1688:
1689: if (ccl->baselist
1690: && (ccl->baselist->bclass!=ocl || ccl->baselist->base!=NAME)) {
1691: // casting second or virtual base to derived?
1692: Nptr = 0;
1693: vcllist->clear();
1694: vcllist=0;
1695: int x = is_unique_base(ccl,ocl->string,0);
1696: //error('d',"x2 %d",x);
1697: switch (x) {
1698: default:
1699: error("cast:%n* ->derived%t*;%n isB more than once",on,ccl,on);
1700: case 0: // unrelated;
1701: break;
1702: case 1:
1703: oo = -Noffset;
1704: if (Nptr)
1705: error("cast:%n* ->derived%t*;%n is virtualB",on,ccl,on);
1706: break;
1707: }
1708: Nvis = 0; // visibility no concern when converting
1709: // from base to derived
1710:
1711:
1712: }
1713: //error('d',"oo %d ee %k",oo,ee->base);
1714: if (oo) { // => ee?ee+offset:0
1715: if (ee->base==ADDROF || ee->base==G_ADDROF)
1716: ee = rptr(ee->tp,ee,oo);
1717: else {
1718: Pexpr p;
1719: extern nin;
1720: nin = 1;
1721: if (ee->not_simple()) { // need temp
1722: Ptype t = ee->tp;
1723: Pname pp = make_tmp('M',t,tbl);
1724: Pname(pp)->n_assigned_to = 1;
1725: ee = new expr(ASSIGN,pp,ee);
1726: ee->tp = t;
1727: p = rptr(t,pp,oo);
1728: }
1729: else
1730: p = rptr(ee->tp,ee,oo);
1731: nin = 0;
1732: Pexpr pp = new expr(QUEST,p,zero);
1733: pp->tp = ee->tp;
1734: pp->cond = ee;
1735: ee = pp;
1736: }
1737: }
1738:
1739: if (ocl->has_base(ccl) && Nvis) {
1740: if (real_cast==0)
1741: error("cast:%n* ->B%t*; privateBC",on,ccl);
1742: else if (warning_opt)
1743: error('w',"cast:%n* ->B%t*; privateBC",on,ccl);
1744: Nvis = 0;
1745: }
1746:
1747: //error('d',"return %d %k %t",ee,ee->base,ee->tp);
1748: return ee;
1749: }
1750:
1751: Pexpr expr::donew(Ptable tbl)
1752: {
1753: Ptype tt = tp2;
1754: Ptype tpx = tt;
1755: bit v = 0;
1756: bit old = new_type;
1757: int init = 0; // non-constructor initialization
1758: new_type = 1;
1759:
1760: tt->dcl(tbl);
1761: new_type = old;
1762: //error('d',"donew %d %d (%k) tt %t",e1,e2,e2?e2->base:0,tt);
1763: if (e1) e1 = e1->typ(tbl);
1764: if (e2) e2 = e2->typ(tbl);
1765: ll:
1766: //error('d',"ll %d",tt->base);
1767: switch (tt->base) {
1768: default:
1769: if ( e1) {
1770: if (v) {
1771: error("Ir for array created using \"new\"");
1772: break;
1773: }
1774: init = 1;
1775: }
1776: // if (e1) {
1777: // error("Ir for nonCO created using \"new\"");
1778: // e1 = 0;
1779: // }
1780: break;
1781: case VEC:
1782: if (v && Pvec(tt)->dim) error("only 1st array dimension can be non-constant");
1783: if (Pvec(tt)->size==0 && Pvec(tt)->dim==0) error("array dimension missingin `new'");
1784: // if (Pvec(tt)->dim==zero) {
1785: // Pvec(tt)->size = 0;
1786: // Pvec(tt)->dim = 0;
1787: // }
1788: v++;
1789: tt = Pvec(tt)->typ;
1790: goto ll;
1791: case TYPE:
1792: tt = Pbase(tt)->b_name->tp;
1793: goto ll;
1794: case VOID:
1795: error("badT for `new': void");
1796: break;
1797: case COBJ:
1798: { Pname cn = Pbase(tt)->b_name;
1799: Pclass cl = Pclass(cn->tp);
1800: Pname icn = (e1 && e1->base!=ELIST) ? e1->tp->is_cl_obj() : 0;
1801: Pclass icl = icn ? Pclass(icn->tp) : 0;
1802:
1803: if (cl->c_abstract) {
1804: error("`new' of abstractC%t",cl);
1805: break;
1806: }
1807:
1808: if (v && e1) {
1809: error("Ir for array ofCO created using \"new\"");
1810: break;
1811: }
1812:
1813: if ((cl->defined&(DEFINED|SIMPLIFIED)) == 0) {
1814: error("new%n;%n isU",cn,cn);
1815: break;
1816: }
1817:
1818: Pname ctor = cl->has_ctor();
1819:
1820: if (ctor) {
1821: if (v) {
1822: Pname ic;
1823: if ((ic = cl->has_ictor())==0) {
1824: error("array ofC%n that does not have aK taking noAs",cn);
1825: break;
1826: }
1827:
1828: if (Pfct(ic->tp)->nargs) {
1829: error("defaultAs forK for array ofC%n",cn);
1830: break;
1831: }
1832: }
1833:
1834: if (icl
1835: && cl->has_itor()==0 // incomplete:
1836: // what if X(Y&) exists
1837: // for class Y : X ?
1838: && (icl==cl || icl->has_base(cl))) {
1839: init = 1;
1840: break;
1841: }
1842: e1 = call_ctor(tbl,0,ctor,e1);
1843: }
1844: else if (e1) {
1845: if (icl==cl || icl->has_base(cl))
1846: init = 1;
1847: else
1848: error("new%n(As ); %n does not have aK",cn,cn);
1849: }
1850: }
1851: }
1852:
1853: if (init) {
1854: Pname tmp = make_tmp('N',tt->addrof(),tbl);
1855: e1 = e1->typ(tbl);
1856: if (tt->check(e1->tp,ASSIGN))
1857: error("badIrT %t for new operator (%t X)",e1->tp,tt);
1858: e1 = new expr(0,tmp,e1);
1859: tmp->assign();
1860: }
1861:
1862: // tp = (v) ? tpx : tpx->addrof();
1863: switch (v) {
1864: case 0:
1865: tp = tpx->addrof();
1866: break;
1867: case 1:
1868: tp = tpx;
1869: break;
1870: default:
1871: tp = tpx;
1872: }
1873: //error('d',"donew(%d) -> %t",v,tp);
1874: return this;
1875: }
1876:
1877: static is_dataMemPtr( Pexpr ee )
1878: /* this is utterly implementation dependent
1879: * called by expr::lval to determine
1880: * const objects bounds to pointers to data members
1881: */
1882: {
1883: Pexpr te = ee->e1;
1884: if ( te == 0 ) return 0;
1885: if ( te->base != PLUS ) return 0;
1886: if ( (te = te->e2) == 0 ) return 0;
1887: if ( te->base != MINUS ) return 0;
1888: if ( (te = te->e1) == 0 ) return 0;
1889: if ( te->base != CAST ) return 0;
1890: if ( (te = te->e1) == 0 ) return 0;
1891: if ( te->tp->base != PTR ) return 0;
1892: if ( Pptr(te)->memof == 0 ) return 0;
1893: return 1;
1894: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.