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