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