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