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