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