|
|
1.1 root 1: /*ident "@(#)ctrans:src/expr3.c 1.7" */
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: expr3.c:
11:
12: type check function calls, casts, and explicit coercions
13:
14: ************************************************************************/
15:
16: #include "cfront.h"
17: #include "size.h"
18:
19: int pr_dominate(Ptype t1, Ptype t2)
20: /*
21: */
22: {
23: Pname cn1 = t1->is_cl_obj();
24: Pname cn2 = t2->is_cl_obj();
25: //error('d',"pr_dominate(%t,%t)",t1,t2);
26:
27: if (cn1==0 || cn2==0) {
28: Ptype p1 = t1->is_ptr();
29: Ptype p2 = t2->is_ptr();
30: if (p1 && p2) { // pointers
31: cn1 = Pptr(p1)->typ->is_cl_obj();
32: cn2 = Pptr(p2)->typ->is_cl_obj();
33: if (cn1==0 || cn2==0) return 0;
34: }
35: else {
36: p1 = t1->is_ref();
37: p2 = t2->is_ref();
38: if (p1 && p2) { // references
39: cn1 = Pptr(p1)->typ->is_cl_obj();
40: cn2 = Pptr(p2)->typ->is_cl_obj();
41: if (cn1==0 || cn2==0) return 0;
42: }
43: // else if (p1 && cn2) {
44: // cn1 = Pptr(p1)->typ->is_cl_obj();
45: // }
46: else
47: return 0; // not the same and not classes
48: }
49: }
50: Pclass c1 = Pclass(cn1->tp);
51: Pclass c2 = Pclass(cn2->tp);
52: //error('d'," c1 : c2 %d; c2 : c1 %d",c1->has_base(c2),c2->has_base(c1));
53: if (c1->has_base(c2)) return 1;
54: if (c2->has_base(c1)) return 2;
55: return 0;
56: }
57:
58: int exact1(Pname,Ptype);
59: static exact2(Pname,Ptype);
60: static exact3(Pname,Ptype);
61:
62: static Pname user_dominate(Pname n1, Pname n2, Pexpr arg)
63: {
64: Pfct f1 = Pfct(n1->tp);
65: Pfct f2 = Pfct(n2->tp);
66:
67: Pname a1 = f1->argtype;
68: Pname a2 = f2->argtype;
69: //error('d',"user_dominate: %n %t %t",n1,f1,f2);
70:
71: for(; a1 && a2; a1 = a1->n_list, a2 = a2->n_list) {
72: Ptype t1 = a1->tp;
73: Ptype t2 = a2->tp;
74: }
75:
76: if (a1 && !a1->n_evaluated) return n1;
77: if (a2 && !a2->n_evaluated) return n2;
78:
79: a1 = f1->argtype;
80: a2 = f2->argtype;
81:
82: Pname prev = 0;
83: Pexpr e = arg;
84:
85: for(; a1 && a2 && e; a1 = a1->n_list, a2 = a2->n_list, e = e->e2) {
86: Ptype t1 = a1->tp;
87: Ptype t2 = a2->tp;
88: Ptype at = e->e1->tp;
89:
90: int j = can_coerce(t1,at);
91: Ptype tt1 = Ncoerce ? Pfct(Ncoerce->tp)->returns : 0;
92: j = can_coerce(t2,at);
93: Ptype tt2 = Ncoerce ? Pfct(Ncoerce->tp)->returns : 0;
94: if(!tt1 || !tt2 || tt1->check(tt2,OVERLOAD))
95: return 0;
96:
97: int one = 0, two = 0;
98: if(exact1(a1,tt1)) one = 4;
99: else if(exact2(a1,tt1)) one = 3;
100: else if(exact3(a1,tt1)) one = 2;
101: else one = 1;
102: if(exact1(a2,tt1)) two = 4;
103: else if(exact2(a2,tt1)) two = 3;
104: else if(exact3(a2,tt1)) two = 2;
105: else two = 1;
106:
107: if(one > two && (!prev || prev==n1)) prev = n1;
108: else if(two > one && (!prev || prev==n2)) prev = n2;
109: else if(one == two && one) ;
110: else return 0;
111: }
112: if(prev) return prev;
113:
114: return 0;
115: }
116:
117: Pname dominate(Pname n1, Pname n2, Pexpr arg, int const_obj, int level)
118: /*
119: the two functions n1 and n2 can each respond to a call using
120: standard conversions. Does the one dominate the other in the
121: sense that all its arguments are identical to the other or
122: classes defived from the class of the corresponding argument
123: of the other.
124:
125: If so return it, otherwise return 0;
126: */
127: {
128: Pname res = 0;
129:
130: Pfct f1 = Pfct(n1->tp);
131: Pfct f2 = Pfct(n2->tp);
132:
133: Pname a1 = f1->argtype;
134: Pname a2 = f2->argtype;
135: Pexpr e = arg;
136: //error('d',"dominate: %n %t %t e %d",n1,f1,f2,e);
137:
138: if (e == 0) {
139: if (const_obj) {
140: if (f1->f_const && f2->f_const==0) return n1;
141: if (f2->f_const && f1->f_const==0) return n2;
142: }
143: else {
144: if (f1->f_const==0 && f2->f_const) return n1;
145: if (f2->f_const==0 && f1->f_const) return n2;
146: }
147: return 0;
148: }
149:
150: for(; a1 && a2 && e; a1 = a1->n_list, a2 = a2->n_list, e = e->e2) {
151: Ptype t1 = a1->tp;
152: Ptype t2 = a2->tp;
153: Ptype at = e->e1->tp;
154: //error('d',"t1 %t t2 %t at %t",t1,t2,at);
155: if (t1==t2 || t1->check(t2,0)==0 )
156: continue;
157: Pptr r1 = t1->is_ref();
158: Pptr r2 = t2->is_ref();
159: //error('d',"const_problem %t %t %t %d",t1,t2,at,const_problem);
160: if (const_problem) { // t1 and t1 differs only in const
161: Pname rr;
162: if (at->check(t1,0)==0 && const_problem==0) {
163: if (t1->is_ptr())
164: rr = n1;
165: else
166: goto nc;
167: }
168: else if (at->check(t2,0)==0 && const_problem==0) {
169: if (t2->is_ptr())
170: rr = n2;
171: else
172: goto nc;
173: }
174: else if (r1 && r1->typ->check(at,0)==0 && const_problem==0)
175: rr = n1;
176: else if (r2 && r2->typ->check(at,0)==0 && const_problem==0)
177: rr = n2;
178: else
179: goto nc;
180:
181: if (res && res!=rr) return 0; // mutual dominace
182: res = rr;
183: continue; // identical
184: }
185: nc:
186: if (r2 && (t1==r2 || t1->check(r2->typ,0)==0)) continue;
187: if (r1 && (t2==r1 || t2->check(r1->typ,0)==0)) continue;
188:
189: Pname rr = 0;
190: if (t1==at || exact1(a1,at)) {
191: rr = n1;
192: if (t2==at || exact1(a2,at))
193: continue;
194: }
195: else if (t2==at || exact1(a2,at))
196: rr = n2;
197: else if (1<level) { // try integral promotion
198: if (exact2(a1,at))
199: rr = n1;
200: if (exact2(a2,at)) {
201: if (rr) rr = 0;
202: else rr = n2;
203: }
204: }
205: if (!rr && 2<level) { // try standard conversions
206: if (exact3(a1,at))
207: rr = n1;
208: if (exact3(a2,at)) {
209: if (rr) rr = 0;
210: else rr = n2;
211: }
212: }
213: if (rr) {
214: if (res && res!=rr) return 0; // mutual dominance
215: res = rr;
216: continue;
217: }
218:
219: int r = pr_dominate(t1,t2);
220: //error('d',"pr1 %d",r);
221: if (r) {
222: Pname rr = r==1?n1:n2;
223: if (res && res!=rr) return 0; // mutual dominace
224: res = rr;
225: continue;
226: }
227:
228: r = pr_dominate(t1,at);
229: //error('d',"pr2 %d",r);
230: if (r==2) {
231: if (res && res!=n1) return 0; // mutual dominace
232: res = n1;
233: r = pr_dominate(t2,at);
234: if (r==2) return 0; // mutual dominace
235: continue;
236: }
237:
238: r = pr_dominate(t2,at);
239: //error('d',"pr3 %d",r);
240: if (r==2) {
241: if (res && res!=n2) return 0; // mutual dominace
242: res = n2;
243: continue;
244: }
245:
246: }
247: //if (a1==0 && a2 && a2->n_initializer==0) return 0; // wrong number of arguments
248: //if (a2==0 && a1 && a1->n_initializer==0) return 0; // wrong number of arguments
249:
250: if (e) {
251: //error('d',"more args %t a1 %t a2 %t",e->e1->tp,a1?a1->tp:0,a2?a2->tp:0);
252: int k1 = f1->nargs_known!=ELLIPSIS;
253: int k2 = f2->nargs_known!=ELLIPSIS;
254: if (a1 && a1->tp->check(e->e1->tp,ASSIGN)==0) return n1;
255: if (a2 && a2->tp->check(e->e1->tp,ASSIGN)==0) return n2;
256: if (k1 && k2) return 0;
257: }
258:
259: if (a1==0 && a2 && a2->n_initializer==0) return 0;
260: if (a2==0 && a1 && a1->n_initializer==0) return 0;
261: if (res==0)
262: if (const_obj) {
263: if (f1->f_const && f2->f_const==0) return n1;
264: if (f2->f_const && f1->f_const==0) return n2;
265: }
266: else {
267: if (f1->f_const==0 && f2->f_const) return n1;
268: if (f2->f_const==0 && f1->f_const) return n2;
269: }
270: //error('d'," -> %n %t",res,res?res->tp:0);
271: return res;
272: }
273:
274: Pname Ntmp;
275:
276: static refd; // initialization routine called by ref_init, do not apply itor
277: static no_sti;
278: extern int stat_init;
279:
280: Pname make_tmp(char c, Ptype t, Ptable tbl)
281: {
282: int dt = 0;
283: Pname tn = tbl->t_name;
284: Pname cn = t->is_cl_obj();
285:
286: if (tn && tn->tp) error('s',"defaultA too complicated");
287: if (cn && Pclass(cn->tp)->has_dtor()) dt = 1;
288: if (Ntmp == 0 && dt ) Ntmp = cn;
289:
290: //error('d',"tbl %d cstmt %d %d sti %d",tbl,Cstmt,Cstmt?Cstmt->memtbl:0,sti_tbl);
291: if (Cstmt) { // make Cstmt into a block
292: if (Cstmt->memtbl == 0) Cstmt->memtbl = new table(4,tbl,0);
293: tbl = Cstmt->memtbl;
294: }
295: else if (tbl == gtbl && no_sti == 0) {
296: if (sti_tbl == 0) sti_tbl = new table(8,gtbl,0);
297: tbl = sti_tbl;
298: }
299:
300: Pname tmpx = new name(make_name(c));
301: tmpx->where = no_where;
302: tmpx->tp = t;
303: (void) t->tsizeof();
304: if ( t->base == COBJ ) {
305: Pclass cl = Pclass(Pbase(t)->b_name->tp);
306: if ( cl->lex_level ) tmpx->lex_level = cl->lex_level;
307: }
308:
309: TOK scop = ARG;
310: if (stat_init && dt) {
311: tmpx->n_sto = STATIC; scop = ARGS;
312: }
313:
314: // ARG[S]: no init; ARGS: static dtor
315: Pname tmp = tmpx->dcl(tbl,scop);
316: delete tmpx;
317:
318: // n_scope == ARGS sets static dtor in simpl2.c
319: tmp->n_scope = (scop==ARG) ? FCT : ARGS;
320: return tmp;
321: }
322:
323: Pexpr init_tmp(Pname tmp, Pexpr init, Ptable tbl)
324: {
325: Pname cn = tmp->tp->is_cl_obj();
326: Pname ct = cn ? Pclass(cn->tp)->has_itor() : 0;
327:
328: tmp->n_assigned_to = 1;
329: //error('d',"init_tmp %n ct %n refd %d",tmp,ct,refd);
330: if (ct) { // must initialize
331: if (refd) {
332: //error('d',"'orrible %k",init->e1->base);
333: switch (init->e1->base) { // 'orrible 'ack
334: case NAME:
335: case REF:
336: case DEREF:
337: if (init->e1->tp->is_ptr())
338: init = init->e1;
339: else
340: init = new expr(G_CM,init,init->e1->address());
341:
342: }
343: if (ct->tp->base == OVERLOAD) ct = Pgen(ct->tp)->fct_list->f; // first fct
344: tbl = 0;
345: }
346: return call_ctor(tbl,tmp,ct,init,DOT);
347: }
348: Pexpr ass = new expr(ASSIGN,tmp,init); // no ctor: can assign
349: ass->tp = tmp->tp;
350: return ass;
351: }
352: /*
353: int exact0(Pname nn, Ptype at)
354: // return 1 if
355: // exact match
356:
357: {
358: if (nn == 0) return 0; //known==ELLIPSIS;
359: Ptype nt = nn->tp;
360: if (at == nt) return 1;
361: //error('d',"exact0 %d",nt->check(at,0));
362: return nt->check(at,0)==0;
363: }
364: */
365:
366: int exact3(Pname nn, Ptype at)
367: /*
368: return 1 if
369: match with standard conversions
370: */
371: {
372: if (nn == 0) return 0; //known==ELLIPSIS;
373: Ptype nt = nn->tp;
374:
375: while(nt->base == TYPE)
376: nt = Pbase(nt)->b_name->tp;
377:
378: if (at == nt) return 1;
379:
380: switch (nt->base) {
381: case RPTR:
382: if (at==zero_type && Pptr(nt)->typ->is_ptr()==0) return 0; //break;
383: if (nt->check(at,COERCE)) {
384: Pptr pt = at->addrof();
385: nt->base = PTR; // handle derived classes
386: if (nt->check(pt,COERCE)) {
387: nt->base = RPTR;
388: delete pt;
389: return 0;
390: }
391: nt->base = RPTR;
392: delete pt;
393: }
394: break;
395: default:
396: switch (at->base) {
397: default:
398: if (nt->check(at,COERCE)) return 0;
399: break;
400: case OVERLOAD:
401: // the actual argument is an overloaded function
402: // we'll try each instance until one matches
403: register Plist gl;
404: int no_match = 1;
405:
406: for (gl = Pgen(at)->fct_list; gl; gl=gl->l) {
407: if (nt->check(gl->f->tp,COERCE)==0) {
408: no_match = 0;
409: break;
410: }
411: }
412:
413: if ( no_match ) return 0;
414: }
415: }
416: return 1;
417: }
418:
419: int exact1(Pname nn, Ptype at)
420: /*
421: return 1 if
422: exact match with
423: T <-> const T
424: X -> X&
425: T* -> const T*
426: T* -> T*const
427: taken into account
428: */
429: {
430: if (nn == 0) return 0;//known==ELLIPSIS;
431: Ptype nt = nn->tp;
432: if (at == nt) return 1;
433:
434: //error('d',"exact1 nt %t at %t",nt,at);
435: if (nt->check(at,0)) {
436: //error('d',"nt %t at %t cp %d",nt,at,const_problem);
437: if (const_problem) return 1; // handle T <-> const T
438:
439: Pptr rt = nt->is_ref(); //handle X -> X&
440: if (rt && (at->check(Pptr(rt)->typ,0)==0 || const_problem)) return 1;
441:
442: Pptr art = at->is_ptr();
443: if (rt && art) return 0; // ptrs do not match refs
444:
445: // handle T* -> const T* and
446: // T* -> T*const
447: if (rt || (rt = nt->is_ptr())) {
448: if (art == 0) art = at->is_ref();
449: if (art) {
450: //error('d',"art %t %t",art->typ,rt->typ);
451: if (art->typ->check(rt->typ,0)) {
452: if (const_problem) return 1;
453: }
454: else // T* -> T*const
455: return 1;
456: }
457: }
458: return 0;
459: }
460: return 1;
461: }
462:
463: Pexpr Ninit; // default argument used;
464: int Nstd; // standard coercion used (derived* =>base* or int=>long or ...)
465:
466: bit exact_match(Pname n, Pexpr arg)
467: /*
468: look for an exact match between "n" and the argument list "arg"
469: This function goes through three stages:
470: (1) exact match (no coercions at all)
471: (2) do integral promotions and float->double and re-try exact match
472: (3) try for unique standard conversions
473:
474: */
475: {
476: Pfct f = Pfct(n->tp);
477: register Pexpr e;
478: register Pname nn;
479:
480: // error('d',"exact_match(%n) %t",n,n->tp);
481:
482: for (e=arg, nn=f->argtype; e; e=e->e2, nn=nn->n_list) {
483: Pexpr a = e->e1;
484: Ptype at = a->tp;
485: if (at->base == ANY) return 0;
486: if (at->base == ZTYPE) at = int_type;
487: if (exact1(nn,at)==0) return 0;
488: }
489:
490: //error('d',"exact %d -> %d",nn,nn?nn->n_initializer!=0:1);
491: if (nn) {
492: Ninit = nn->n_initializer;
493: return Ninit!=0;
494: }
495:
496: //error('d',"return 1");
497: return 1; // exact match without any promotions
498: }
499:
500: int exact2(Pname nn, Ptype at)
501: /*
502: return 1 if
503: do integral promotion and float->double on at, then match
504: */
505: {
506: //error('d',"exact2 nt %t at %t",nn?nn->tp:0,at);
507: while(at->base == TYPE)
508: at = Pbase(at)->b_name->tp;
509:
510: switch (at->base) {
511: case EOBJ:
512: at = Penum(Pbase(at)->b_name->tp)->e_type;
513: break;
514: case ZTYPE:
515: at = int_type;
516: break;
517: case CHAR:
518: case SHORT:
519: at = (Pbase(at)->b_unsigned && at->tsizeof()==SZ_INT) ? uint_type : int_type;
520: break;
521: case FLOAT:
522: at = double_type;
523: }
524:
525: if (nn == 0) return 0;//known==ELLIPSIS;
526: Ptype nt = nn->tp;
527: //error('d'," exact2 nt %t at %t",nt,at);
528: if (at == nt) return 1;
529: if (nt->check(at,0)) {
530: if (const_problem) return 1;
531:
532: Pptr rt = nt->is_ref(); // handle X -> X&
533: if (rt && (at->check(Pptr(rt)->typ,0)==0 || const_problem)) return 1;
534:
535: Pptr art = at->is_ptr();
536: if (rt && art) return 0; // ptrs do not match refs
537:
538: // handle T* -> const T* and
539: // T* -> T*const
540: if (rt || (rt = nt->is_ptr())) {
541: if (art == 0) art = at->is_ref();
542: if (art) {
543: if (art->typ->check(rt->typ,0)) {
544: if (const_problem) return 1;
545: }
546: else // T* -> T*const
547: return 1;
548: }
549: }
550: return 0;
551: }
552: return 1;
553: }
554:
555: bit prom_match(Pname n, Pexpr arg)
556: /*
557: look for an exact match between "n" and the argument list "arg"
558: using integral promotions and float->double
559:
560: */
561: {
562: Pfct f = Pfct(n->tp);
563: register Pexpr e;
564: register Pname nn;
565:
566: // error('d',"prom_match(%n) %t",n,n->tp);
567:
568: for (e=arg, nn=f->argtype; e; e=e->e2, nn=nn->n_list) {
569: Pexpr a = e->e1;
570: Ptype at = a->tp;
571: if (at->base == ANY) return 0;
572:
573: if (exact2(nn,at)==0) return 0;
574: }
575:
576: if (nn) {
577: Ninit = nn->n_initializer;
578: return Ninit!=0;
579: }
580:
581: return 1; // exact match with promotions
582: }
583:
584: bit std_match(Pname n, Pexpr arg)
585: /*
586: look for an exact match between "n" and the argument list "arg"
587: using standard conversions
588:
589: */
590: {
591: Pfct f = Pfct(n->tp);
592: register Pexpr e;
593: register Pname nn;
594:
595: // error('d',"std_match(%n) %t",n,n->tp);
596:
597: for (e=arg, nn=f->argtype; e; e=e->e2, nn=nn->n_list) {
598: Pexpr a = e->e1;
599: Ptype at = a->tp;
600:
601: if (at->base == ANY) return 0;
602: if ( exact3(nn,at) == 0) return 0;
603: }
604:
605: if (nn) {
606: Ninit = nn->n_initializer;
607: return Ninit!=0;
608: }
609:
610: return 1;
611: }
612:
613: Pname Ncoerce;
614: int ref_cast;
615:
616: bit can_coerce(Ptype t1, Ptype t2)
617: /* return number of possible coercions of t2 into t1,
618: Ncoerce holds a coercion function (not constructor), if found
619: */
620: {
621: int zz = 0;
622: Ncoerce = 0;
623: if (t2->base == ANY) return 0;
624: // error('d',"can_coerce t1 %t t2 %t",t1, t2);
625:
626: while(t1->base == TYPE)
627: t1 = Pbase(t1)->b_name->tp;
628:
629: switch (t1->base) {
630: case RPTR:
631: while(t2->base == TYPE)
632: t2 = Pbase(t2)->b_name->tp;
633:
634: switch (t2->base) {
635: // case VEC:
636: // case PTR:
637: // case RPTR:
638: // if (t1->check(t2,COERCE) == 0) return 1;
639: default:
640: { Ptype tt2 = t2->addrof();
641: if (t1->check(tt2,COERCE) == 0) return 1;
642: if (ref_cast) break;//return 0; // (T&): no coercions
643: // except operator T&()
644: Ptype tt1 = Pptr(t1)->typ;
645: while (tt1->base==TYPE) tt1 = Pbase(tt1)->b_name->tp;
646: int bc;
647: if ( tt1->base != PTR && tt1->base != RPTR ) {
648: bc = Pbase(tt1)->b_const;
649: Pbase(tt1)->b_const = 0;
650: }
651: int i = can_coerce(tt1,t2);
652: if ( tt1->base != PTR && tt1->base != RPTR )
653: Pbase(tt1)->b_const = bc;
654: if (i) return i;
655: zz = 1;
656: }
657: }
658: }
659:
660: Pname c1 = t1->is_cl_obj();
661: Pname c2 = t2->is_cl_obj();
662: int val = 0;
663: if (ref_cast || zz) goto oper_coerce;
664: if (c1) {
665: Pclass cl = Pclass(c1->tp);
666: if (c2 && c2->tp==cl) return 1;
667:
668: // A more comprehensive test for template classes
669: if (c2 && (Pclass(c1->tp)->same_class(Pclass(c2->tp))))
670: return 1 ;
671:
672: /* look for constructor
673: with one argument
674: or with default for second argument
675: of acceptable type
676: */
677: Pname ctor = cl->has_ctor();
678: if (ctor == 0) goto oper_coerce;
679: register Pfct f = Pfct(ctor->tp);
680: //error('d',"ctor %n f %t",ctor,f);
681: switch (f->base) {
682: case FCT:
683: switch (f->nargs) {
684: case 1:
685: one:
686: { Ptype tt = f->argtype->tp;
687: if (tt->check(t2,COERCE)==0)
688: val = 1;
689: else if (const_problem) {
690: Pptr p1 = tt->is_ptr_or_ref();
691: if (p1==0 || p1->typ->tconst()) val = 1;
692: }
693: if (tt = tt->is_ref()) {
694: Pptr pt = t2->addrof(); // handle derived classed
695: tt->base = PTR;
696: if (tt->check(pt,COERCE) == 0) val = 1;
697: tt->base = RPTR;
698: delete pt;
699: }
700: goto oper_coerce;
701: }
702: default:
703: if (f->argtype->n_list->n_initializer) goto one;
704: case 0:
705: goto oper_coerce;
706: }
707: case OVERLOAD:
708: { register Plist gl;
709:
710: for (gl=Pgen(f)->fct_list; gl; gl=gl->l) { // look for match
711: Pname nn = gl->f;
712: Pfct ff = Pfct(nn->tp);
713:
714: switch (ff->nargs) {
715: case 0:
716: break;
717: case 1:
718: over_one:
719: { Ptype tt = ff->argtype->tp;
720: //error('d',"over one %t %t -> %d %d",tt,t2,tt->check(t2,COERCE),const_problem);
721: if (tt->check(t2,COERCE)==0)
722: val = 1;
723: else if (const_problem) {
724: Pptr p1 = tt->is_ptr_or_ref();
725: if (p1==0 || p1->typ->tconst()) val = 1;
726: }
727: if (tt=tt->is_ref()) {
728: Pptr pt = t2->addrof(); // handle derived classed
729: tt->base = PTR;
730: if (tt->check(pt,COERCE) == 0) {
731: tt->base = RPTR;
732: delete pt;
733: val = 1;
734: goto oper_coerce;
735: }
736: tt->base = RPTR;
737: delete pt;
738: }
739: break;
740: }
741: default:
742: if (ff->argtype->n_list->n_initializer) goto over_one;
743: }
744: }
745: goto oper_coerce;
746: }
747: default:
748: error('i',"cannot_coerce(%k)\n",f->base);
749: }
750: }
751:
752: oper_coerce:
753: //error('d',"oper_coerce %d",val);
754: if (c2) {
755: Pclass cl = Pclass(c2->tp);
756: int std = 0;
757: int oval = val;
758: extern Pname conv_dominates(Pname,Pname);
759: for (Pname ox, on=cl->conv; on; on=ox) {
760: ox = on->n_list;
761: // error( 'd', "can_coerce: ox: %s on: %s tp: %k", ox?ox->string:"", on->string, on->tp->base );
762: Plist gl = 0;
763: if ( on->tp->base == OVERLOAD ) {
764: gl = Pgen(on->tp)->fct_list;
765: on = gl->f;
766: gl = gl->l;
767: }
768:
769: overlist:
770: // error( 'd', "can coerce: on: %n tp: %t gl: %d", on, on->tp, gl );
771:
772: Pfct f = Pfct(on->tp);
773: Nstd = 0;
774: if (t1->check(f->returns,COERCE) == 0) {
775: if (Nstd==0) { // forget solutions involving standard conversions
776: Pname old = Ncoerce;
777: if (std) { // forget
778: val = oval+1;
779: std = 0;
780: Ncoerce = on;
781: }
782: else if (Ncoerce == 0) {
783: // val = 1;
784: val++;
785: Ncoerce = on;
786: }
787: else if ((Ncoerce = conv_dominates(Ncoerce,on))==0) {
788: if (val == 1) {
789: //error('d',"val==1 on %n old %n",on,old);
790: Ptype ton = Pfct(on->tp)->returns;
791: Ptype tco = Pfct(old->tp)->returns;
792: if (t1->check(ton,0)==0)
793: ;
794: else if (t1->check(tco,0)==0)
795: on = old;
796: else
797: val++;
798: }
799: else
800: val++;
801: Ncoerce = on;
802: }
803: }
804: else { // take note only if no exact match seen
805: if (Ncoerce==0 || on->tp->check(Ncoerce->tp,0)) {
806: if (val==0 || std) {
807:
808: if (Ncoerce) Ncoerce = conv_dominates(Ncoerce,on);
809: if (Ncoerce == 0) {
810: Ncoerce = on;
811: val++;
812: std = 1;
813: }
814: }
815: }
816: }
817: }
818: // error( 'd', "can_coerce: gl: %d", gl );
819: if ( gl ) {
820: on = gl->f;
821: gl = gl->l;
822: goto overlist; // must walk list of overloaded instances
823: }
824: }
825: }
826: //error('d',"val %d",val);
827: if (val) return val;
828: if (c1 && Pclass(c1->tp)->has_itor()) return 0;
829: //error('d',"%t->check(%t) -> %d",t1,t2,t1->check(t2,COERCE));
830: if (t1->check(t2,COERCE)) return 0;
831: return 1;
832: }
833:
834: int gen_coerce(Pname n, Pexpr arg)
835: /*
836: look to see if the argument list "arg" can be coerced into a call of "n"
837: 1: it can
838: 0: it cannot or it can be done in more than one way
839: */
840: {
841: Pfct f = (Pfct) n->tp;
842: register Pexpr e;
843: register Pname nn;
844:
845: //error('d',"gen_coerce(%n,%d) %t",n,arg,n->tp);
846: for (e=arg, nn=f->argtype; e; e=e->e2, nn=nn->n_list) {
847: if (nn == 0) return f->nargs_known==ELLIPSIS;
848: Pexpr a = e->e1;
849: Ptype at = a->tp;
850: int i = can_coerce(nn->tp,at);
851: if (i != 1) return 0;
852: }
853: if (nn && nn->n_initializer==0) return 0;
854: return 1;
855: }
856:
857:
858: Pname Nover;
859: // int Nover_coerce;
860:
861: int over_call(Pname n, Pexpr arg)
862: /*
863: return 4 if n(arg) can be performed without coercion of arg
864: return 3 if n(arg) can be performed only with promotion coercion of arg
865: return 2 if n(arg) can be performed only with standard coercion of arg
866: return 1 if n(arg) can be performed only with user defined coercion of arg
867: return 0 if n(arg) is an error
868: Nover is the function found, if any
869: Nstd is the number of standard coercions used
870: */
871: {
872: register Plist gl;
873: Pgen g = Pgen(n->tp);
874: if (arg && arg->base!= ELIST) error('i',"ALX");
875:
876: //error('d',"over_call(%n) %k",n,n->tp->base);
877: extern suppress_error;
878: suppress_error = 1;
879: // Nover_coerce = 0;
880: Nstd = 0;
881: switch (g->base) {
882: default: error('i',"over_call(%t)\n",g);
883: case OVERLOAD: break;
884: case FCT:
885: Nover = n;
886: Ninit = 0;
887: if (exact_match(n,arg)) {suppress_error = 0; return 4;}
888: if (prom_match(n,arg)) {suppress_error = 0; return 3;}
889: if (std_match(n,arg) && Ninit==0) {suppress_error = 0; return 2;}
890: Nstd = 0;
891: suppress_error = 0;
892: return gen_coerce(n,arg);
893: }
894:
895: Pname exact = 0;
896: int no_exact = 0;
897: int ret = 0;
898: Pname nret;
899: for (gl=g->fct_list; gl; gl=gl->l) { /* look for match */
900: Nover = gl->f;
901: Ninit = 0;
902: Nstd = 0;
903: if (exact_match(Nover,arg)) {suppress_error = 0; return 4;} // no coercion
904: // if (prom_match(Nover,arg)) return 3; // only promotion
905: // if (std_match(Nover,arg) && Ninit==0) return 2; // only built-in conversion
906: if (ret<3 && prom_match(Nover,arg)) {
907: nret = Nover;
908: ret = 3;
909: }
910: if (ret<2 && std_match(Nover,arg) && Ninit==0) {
911: nret = Nover;
912: ret = 2;
913: }
914: }
915:
916: suppress_error = 0;
917: if (ret) {
918: Nover = nret;
919: return ret;
920: }
921:
922: Nover = 0;
923: for (gl=g->fct_list; gl; gl=gl->l) { /* look for coercion */
924: Pname nn = gl->f;
925: if (gen_coerce(nn,arg)) {
926: Nover = nn;
927: return 1;
928: }
929: }
930: return 0;
931:
932: }
933:
934: Ptype expr::call_fct(Ptable tbl)
935: /*
936: check "this" call:
937: e1(e2)
938: e1->typ() and e2->typ() has been done
939: */
940: {
941: Pfct f;
942: Pname fn;
943: int x;
944: int k;
945: Pname nn;
946: Pexpr e;
947: Ptype t;
948: Pexpr arg = e2;
949: Ptype t1 = e1?e1->tp:0;
950: int argno;
951: Pexpr etail = 0;
952: bit no_change = 0;
953: Pname no_virt = 0; // set if explicit qualifier was used: c::f()
954: Pname chk = 0; // set if visibility check is needed
955: // that is if function name might have been
956: // found without use of find_name()
957: int const_obj = 0;
958:
959: if (t1 == any_type) return any_type;
960:
961: switch (base) {
962: case CALL:
963: case G_CALL: break;
964: default: error('i',"call_fct(%k)",base);
965: }
966:
967: // error('d',"call %d %k %n arg %d",this,e1->base,e1->base==NAME?e1:0,arg);
968: if (t1 == 0) error('i',"call_fct(e1=%d,e1->tp=%t)",e1,t1);
969: if (arg && arg->base!=ELIST) error('i',"badAL%d%k",arg,arg->base);
970:
971: switch (e1->base) {
972: case NAME:
973: fn = Pname(e1);
974: //error('d',"name %n %k",fn,fn->n_oper);
975: switch (fn->n_oper) {
976: case 0:
977: case CTOR:
978: case DTOR:
979: case TYPE:
980: case NEW:
981: case DELETE:
982: break;
983: default: // real operator: check for operator+(1,2);
984: if (arg == 0) break;
985: Pexpr a = arg->e1; // first operand
986:
987: if (Pfct(fn->tp)->memof // obj.operator(1) is OK
988: || a->tp->is_cl_obj()
989: || a->tp->is_ref()) break;
990: a = arg->e2;
991: if (a == 0) // unary
992: error("%k of basicT",fn->n_oper);
993: else { // binary
994: a = a->e1; // second operand
995: if (a->tp->is_cl_obj() || a->tp->is_ref()) break;
996: error("%k of basicTs",fn->n_oper);
997: }
998: break;
999: }
1000: break;
1001: case REF:
1002: case DOT:
1003: no_virt = Pname(e1->n_initializer);
1004: e1->n_initializer = 0;
1005: if (e1 && e1->e1) {
1006: Ptype t = e1->e1->tp;
1007: Pptr tt = t->is_ptr_or_ref();
1008: Ptype ft = tt ? tt->typ : t;
1009: Pexpr ee = e1->e1;
1010: const_obj = ft->tconst();
1011: while (ee && (ee->base==DOT || ee->base==REF)) {
1012: Pexpr m = ee->mem;
1013: if ( ee->base==REF && m->tp && m->tp->is_ptr())
1014: break;
1015: ee = ee->e1;
1016: }
1017: if (ee) {
1018: Ptype ttt = ee->tp;
1019: int tc;
1020: switch (e1->base) {
1021: case REF:
1022: Pptr p = ttt?ttt->is_ptr():0;
1023: if (p && p->typ->tconst())
1024: const_obj = 1;
1025: break;
1026: case DOT:
1027: tc = ttt ? ttt->tconst() : 0;
1028: if(ttt && tc && (!strict_opt || tc!=2))
1029: const_obj = 1;
1030: }
1031: }
1032: }
1033: case MDOT:
1034: { Pexpr n = e1->mem;
1035: lxlx:
1036: switch (n->base) {
1037: case MDOT:
1038: // reverse mdot (see expr::print())
1039: // p->a.b() => (&p->a)->b() => b(&p->a)
1040: // or p->a->b() => (p->a)->b() => b(p->a)
1041: // or oo.a.b() => (&oo.a)->b() => b(&oo.a)
1042: // or oo.a->b() => (oo.a)->b() => b(oo.a)
1043: {
1044: Pexpr r = e1;
1045: Pexpr p = r->e1;
1046: for (Pexpr m = r->mem; m->base==MDOT; m = r->mem) {
1047: p = new mdot(m->string2,p);
1048: p->i1 = m->i1+2;
1049: p->tp = p->mem->tp;
1050: r->mem = m->mem;
1051: r->e1 = p;
1052: }
1053: }
1054: case REF:
1055: case DOT:
1056: n = n->mem;
1057: goto lxlx;
1058: case NAME:
1059: break;
1060: default:
1061: error('i',"ref %k",n->base);
1062: }
1063: fn = Pname(n);
1064: //error('d',"mem %n",fn);
1065: break;
1066: }
1067: case MEMPTR:
1068: default:
1069: fn = 0;
1070: };
1071:
1072: lll:
1073: //error('d',"lll: %t %k",t1,t1->base);
1074: switch (t1->base) {
1075: case TYPE:
1076: t1 = Pbase(t1)->b_name->tp;
1077: goto lll;
1078:
1079: case PTR: // pf() allowed as shorthand for (*pf)()
1080: switch (Pptr(t1)->typ->base) {
1081: case FCT:
1082: case OVERLOAD:
1083: if (Pptr(t1)->memof) error("O missing in call throughP toMF");
1084: t1 = Pptr(t1)->typ;
1085: fn = 0;
1086: goto lll;
1087: }
1088:
1089: default:
1090: if (fn)
1091: error("call of%n;%n is a%t",fn,fn,e1->tp);
1092: else
1093: error("call of%kE ofT%t",e1->base,e1->tp);
1094:
1095: case ANY:
1096: return any_type;
1097:
1098: case OVERLOAD:
1099: { register Plist gl;
1100: Pgen g = Pgen(t1);
1101: Pname found = 0;
1102: Pname exact = 0;
1103: int no_exact = 0;
1104: int no_gen = 0;
1105:
1106: for (gl=g->fct_list; gl; gl=gl->l) { // look for exact match
1107: register Pname nn = gl->f;
1108: if (exact_match(nn,arg)) {
1109: //error('d',"found exact %n %t",nn,nn->tp);
1110: if (found) {
1111: // check if one fct dominates the other
1112: Pname d = dominate(found,nn,arg,const_obj,0);
1113: if (d)
1114: nn = d;
1115: else
1116: error("two exact matches for%n:%t and%t",nn,nn->tp,found->tp);
1117: }
1118: found = nn;
1119: }
1120: }
1121: //error('d',"found exact2 %n",found);
1122: if (found) goto fnd;
1123:
1124: Pname mvec[20];
1125:
1126: /****************************************************************************
1127: the next 2 loops have been commented out to eliminate the rule that calls
1128: requiring only promotions and standard conversions are preferred over
1129: calls requiring user-defined conversions.
1130:
1131: for (gl=g->fct_list; gl; gl=gl->l) { // look for exact match
1132: register Pname nn = gl->f;
1133:
1134: if (prom_match(nn,arg)) {
1135: if (found) {
1136: // check if one fct dominates the other
1137: Pname d = dominate(found,nn,arg,const_obj,1);
1138: if (d)
1139: nn = d;
1140: else
1141: error("two exact matches (after integral promotions) for%n:%t and%t",nn,nn->tp,found->tp);
1142: }
1143: found = nn;
1144: }
1145: }
1146: //error('d',"found exact2 %n",found);
1147: if (found) goto fnd;
1148:
1149: // for (gl=g->fct_list; gl; gl=gl->l) { // look for exact match
1150: // register Pname nn = gl->f;
1151: //
1152: // if (exact_match(nn,arg) || prom_match(nn,arg)) {
1153: // found = nn;
1154: // goto fnd;
1155: // }
1156: // }
1157:
1158: for (gl=g->fct_list; gl; gl=gl->l) { // look for match
1159: // with standard conversion
1160: register Pname nn = gl->f;
1161: Ninit = 0;
1162: Nstd = 0;
1163: if (std_match(nn,arg)) {
1164: // if (Nstd == 0) {
1165: // found = nn;
1166: // goto fnd;
1167: // }
1168: if (exact) {
1169: // check if one fct dominates the other
1170: Pname d = dominate(exact,nn,arg,const_obj,2);
1171: if (d == 0) {
1172: mvec[no_exact++] = nn;
1173: // no_exact++;
1174: // error("two standard conversions possible for%n: %t and %t",fn,exact->tp,nn->tp);
1175: }
1176: else
1177: exact = d;
1178: }
1179: else
1180: exact = nn;
1181: }
1182:
1183: }
1184:
1185: //error('d',"excact %n",exact);
1186: if (exact) {
1187: if (no_exact) {
1188: while (no_exact) {
1189: Pname d = dominate(exact,mvec[--no_exact],arg,const_obj,2);
1190: if (d)
1191: exact = d;
1192: else
1193: error("two standard conversions possible for%n: %t and %t",fn,exact->tp,mvec[no_exact]->tp);
1194: }
1195:
1196: }
1197: //error('d',"found exact3 %n",found);
1198: found = exact;
1199: goto fnd;
1200: }
1201:
1202: this is the end of the commented out section.
1203: ************************************************************************/
1204:
1205: for (gl=g->fct_list; gl; gl=gl->l) { /* look for coercion */
1206: register Pname nn = gl->f;
1207: if (prom_match(nn,arg) ||
1208: std_match(nn,arg) ||
1209: gen_coerce(nn,arg)) {
1210: //error('d',"user2 %n %t",nn,nn->tp);
1211: if (found) {
1212: // check if one fct dominates the other
1213: Pname d = dominate(found,nn,arg,const_obj,3);
1214: //error('d',"dom d %d",d);
1215: if (d == 0) d = user_dominate(found,nn,arg);
1216: if (d == 0) {
1217: mvec[no_gen++] = nn;
1218: }
1219: else
1220: found = d;
1221: }
1222: else
1223: found = nn;
1224: }
1225: }
1226: if(found) {
1227: while(no_gen) {
1228: Pname d = dominate(found,mvec[--no_gen],arg,const_obj,3);
1229: if(d==0) d = user_dominate(found,mvec[no_gen],arg);
1230: if(d)
1231: found = d;
1232: else {
1233: //error("ambiguousA for%n: %t and %t",fn,found->tp,mvec[no_gen]->tp);
1234: error("ambiguous call of%n: %t and %t",fn,found->tp,mvec[no_gen]->tp);
1235: }
1236: }
1237: }
1238: fnd:
1239: //error('d',"fnd %t",found?found->tp:0);
1240: if (found) {
1241: overFound = chk = fn = found;
1242: f = Pfct(fn->tp);
1243: }
1244: else {
1245: error("badAL for%n (no match against any %n)",fn,fn);
1246: return any_type;
1247: }
1248: break;
1249: }
1250: case FCT:
1251: f = Pfct(t1);
1252: if (fn) {
1253: switch (fn->n_oper) {
1254: case CTOR:
1255: case TYPE:
1256: chk = fn;
1257: }
1258: }
1259: }
1260:
1261: //error('d',"chk %n",chk);
1262: if (chk) {
1263: Ptype t = 0;
1264: Pexpr ee = e1->e1;
1265:
1266: switch (e1->base) {
1267: case REF: // ptr->chk()
1268: if (ee == 0) { // 0->x() fudge handling new x()
1269: check_visibility(chk,no_virt,Pclass(chk->n_table->t_name->tp),tbl,cc->nof);
1270: break;
1271: };
1272: t = ee->tp;
1273: while(t->base==TYPE) t = Pbase(t)->b_name->tp;
1274: t = Pptr(t)->typ;
1275: break;
1276: case DOT: // obj.chk()
1277: t = ee->tp;
1278: }
1279:
1280: Pname cn = t?t->is_cl_obj():0;
1281: Pclass cl = cn?Pclass(cn->tp):0; // class of ``this'' for chk
1282:
1283: if (cl) {
1284: if (chk->n_oper==CTOR
1285: && chk->n_protect
1286: && cc->nof
1287: && cc->nof->n_oper==CTOR)
1288: // BUG: cannot handle protected base
1289: // class constructor
1290: ;
1291: else {
1292: check_visibility(chk,no_virt,cl,tbl,cc->nof);
1293: }
1294: }
1295: }
1296:
1297: if (fn && f->returns->is_cl_obj() && f->f_result==0) {
1298: // protect against class cn; cn f(); ... class cn { cn(cn&); ... };
1299: make_res(f);
1300: //error('d',"returns %t",f->returns);
1301: f->returns->tsizeof(); // make sure it is declared
1302: }
1303:
1304: //error('d',"fn %n %t printed %d",fn,fn?fn->tp:0,fn?fn->n_dcl_printed:0);
1305: if (fn && fn->n_dcl_printed==0) {
1306: if (f->f_inline==0 && f->f_imeasure) {
1307: extern void uninline(Pname fn);
1308: uninline(fn);
1309: }
1310:
1311: // ensure printout of class declaration:
1312: for (Pname nn=f->argtype; nn; nn=nn->n_list)
1313: if (nn->tp->is_cl_obj()) (void) nn->tp->tsizeof();
1314:
1315: fn->dcl_print(0);
1316: }
1317:
1318: if (no_virt && f->f_static==0) {
1319: if (e1->base==REF || e1->base==DOT) e1->n_initializer = fn;
1320: }
1321: else
1322: fct_name = fn;
1323: //error('d',"fn %n %t %d %d",fn,f,f->f_this,f->f_static);
1324: if (f->f_this) { //SSS call of non-static memberfunction
1325: switch (e1->base) {
1326: case MEMPTR:
1327: case REF:
1328: case DOT:
1329: break;
1330: default:
1331: error("O orP missing for%n ofT %t",fct_name,f);
1332: }
1333: }
1334: else if (fn) { //SSS call of static function
1335: sss:
1336: switch (e1->base) {
1337: case REF:
1338: case DOT:
1339: e1 = e1->mem;
1340: goto sss;
1341: }
1342: }
1343:
1344: if (fn) fn->use(); // a patch: ctors are sometimes not use()d
1345:
1346: if (f->f_const==0
1347: && (fn==0 || (fn->n_oper!=CTOR && fn->n_oper!=DTOR))) { //CCC
1348: Pexpr ee = e1->e1;
1349: // while (ee && (ee->base==DOT || ee->base==REF)) ee = ee->e1;
1350: while (ee && (ee->base==DOT || ee->base==REF)) {
1351: Pexpr m = ee->mem;
1352: // error('d', "m: %k tp %t", m?m->base:0, m?m->tp:0 );
1353: if ( ee->base==REF && m->tp && m->tp->is_ptr())
1354: break;
1355: ee = ee->e1;
1356: }
1357: // error('d', "ee: %k tp %k", ee?ee->base:0, ee?ee->tp->base:0);
1358:
1359: if (ee) {
1360: Ptype tt = ee->tp;
1361: switch (e1->base) {
1362: case REF:
1363: { Pptr p = tt?tt->is_ptr():0;
1364: if (p && p->typ->tconst())
1365: error(strict_opt?0:'w',"non-constMF%n called for constO (anachronism)",fn);
1366: // is really an error, but only warn to help transition
1367: break;
1368: }
1369: case DOT:
1370: int tc = tt ? tt->tconst() : 0;
1371: if (tt && tc && (!strict_opt || tc!=2))
1372: error(strict_opt?0:'w',"non-constMF%n called for constO (anachronism)",fn);
1373: // is really an error, but only warn to help transition
1374: }
1375: }
1376: }
1377:
1378: t = f->returns;
1379: x = f->nargs;
1380: k = f->nargs_known;
1381:
1382: e = arg;
1383: if (k == 0) goto rlab;
1384:
1385: for (nn=f->argtype, argno=1; e||nn; nn=nn->n_list, e=etail->e2, argno++) {
1386: Pexpr a;
1387: int save_base = 0;
1388: char* save_name = 0;
1389:
1390: if (e) {
1391: a = e->e1;
1392: etail = e;
1393:
1394: if (nn) { /* type check */
1395: Ptype t1 = nn->tp;
1396: //error('d',"argtp %t etp %t a %k",t1,a->tp,a->base);
1397:
1398: while(t1->base == TYPE)
1399: t1 = Pbase(t1)->b_name->tp;
1400:
1401: switch (t1->base) {
1402: case RPTR:
1403: { Ptype pt = Pptr(t1)->typ;
1404: if (pt->base != FCT ||
1405: ( pt->base == FCT &&
1406: pt->check(a->tp,0)))
1407: a = ref_init(Pptr(nn->tp),a,tbl);
1408: goto cbcb;
1409: }
1410: case COBJ:
1411: if (a->base!=G_CM
1412: || nn->tp->check(a->tp,ASSIGN))
1413: a = class_init(0,t1,a,tbl);
1414: else
1415: a->e2=class_init(0,t1,a->e2,tbl);
1416: if (nn->n_xref) {
1417: // (temp.ctor(arg),&arg)
1418: a = a->address();
1419: }
1420: else {
1421: // defend against:
1422: // int f(X); ... X(X&);
1423: Pname cln = Pbase(t1)->b_name;
1424: if (cln && Pclass(cln->tp)->has_itor()) {
1425: // mark X(X&) arguments
1426: nn->n_xref = 1;
1427: a = a->address();
1428: }
1429: }
1430: cbcb:
1431: //error('d',"cbcb: a %d %k %t",a->base,a->base,a->tp);
1432: if (a->base==G_CM) {
1433: if (a->e1->base==DEREF) a->e1 = a->e1->e2; // (*e1,e2) => (e1,e2)
1434: //error('d'," a %d %k",a->e1->base,a->e1->base);
1435: if (a->e1->base==G_CALL
1436: && Pname(a->e1->fct_name)
1437: && Pname(a->e1->fct_name)->n_oper==CTOR
1438: && (a->e2->base==G_ADDROF || a->e2->base==ADDROF)) {
1439: a = a->e1; // (ctor(&tmp),&tmp) => ctor(&tmp)
1440: //error('d',"tmp %k %n",a->e2->base,a->e2->e2);
1441: goto cccc;
1442: }
1443: else if (a->e2->base==G_ADDROF
1444: && a->e2->e2->base==NAME) {
1445: cccc:
1446: //error('d',"cccc: a %d %k %t",a->base,a->base,a->tp);
1447: if (t1->base==RPTR
1448: && Pptr(t1)->typ->tconst()==0) { // temporary used
1449: if (warning_opt)
1450: error('w',"temporary used for non-const%tA",nn->tp);
1451: else {
1452: Ptype atp = a->tp;
1453: if (atp==void_type
1454: && a->base==G_CALL
1455: && a->e1->tp->base==FCT)
1456: atp = Pfct(a->e1->tp)->s_returns;
1457:
1458: Ptype tt = t1->is_ref();
1459: //error('d',"tt %t atp %t",tt,atp);
1460: if (tt) {
1461: if (Pptr(tt)->typ->tsizeof()!=atp->tsizeof()) { // sliced
1462: Ptype aat = atp->is_ptr_or_ref();
1463: if (aat==0
1464: || Pptr(tt)->typ->tsizeof()!=Pptr(aat)->typ->tsizeof())
1465: error('w',"temporary used for non-const%tA",nn->tp);
1466: }
1467: }
1468: else if (t1->tsizeof()!=atp->tsizeof()) // sliced
1469: error('w',"temporary used for non-const%tA",nn->tp);
1470: }
1471:
1472: // if (warning_opt // blabber
1473: // || t1->tsizeof()!=a->tp->tsizeof())) // sliced
1474: // error('w',"temporary used for non-const%tA",nn->tp);
1475:
1476: }
1477: }
1478: }
1479: e->e1 = a;
1480: break;
1481: case ANY:
1482: goto rlab;
1483: case PTR:
1484: {
1485: save_base = e->e1->base;
1486: if(a->tp->base==OVERLOAD)
1487: save_name = Pgen(a->tp)->fct_list->f->string;
1488: Pexpr te_a = a;
1489: e->e1 = a = ptr_init(Pptr(t1),a,tbl);
1490: no_change = (te_a == a);
1491: // if (x==a || x==a->e2) goto def; // needs checking
1492: if (Pchecked == 0) goto def;
1493: break;
1494: }
1495: // e->e1 = a = ptr_init(Pptr(t1),a,tbl);
1496: // goto def;
1497: case CHAR:
1498: case SHORT:
1499: case INT:
1500: // if (a->base==ICON && a->tp==long_type)
1501: // error('w',"long constantA for%n,%kX",fn,t1->base);
1502: { Ptype t = a->tp;
1503: while(t->base == TYPE)
1504: t = Pbase(t)->b_name->tp;
1505:
1506: switch (t->base) {
1507: case LONG:
1508: case FLOAT:
1509: case DOUBLE:
1510: case LDOUBLE:
1511: error('w',"A%d: %t passed as %t",argno,a->tp,t1);
1512: }
1513: }
1514: // no break
1515: case LONG:
1516: if (Pbase(t1)->b_unsigned
1517: && a->base==UMINUS
1518: && a->e2->base==ICON)
1519: error('w',"negativeA for%n, unsignedX",fn);
1520: default:
1521: def:
1522: { Pexpr x = try_to_coerce(t1,a,"argument",tbl);
1523: //error('d',"x %d t1 %t nn %t a1 %t",x,t1,nn->tp,a->tp);
1524: if (x) {
1525: if (Pchecked == 0 && no_change) {
1526: Pexpr te_x = ptr_init(Pptr(t1), x, tbl);
1527:
1528: if ( te_x != x ) e->e1 = a = te_x; else e->e1=x;
1529: }
1530: else
1531: e->e1 = x;
1532: }
1533: else if (nn->tp->check(a->tp,ARG)) {
1534: error("badA %dT for%n:%t (%tX)",argno,fn,a->tp,nn->tp);
1535: return any_type;
1536: }
1537: }
1538: }
1539:
1540: Pexpr tt = e->e1;
1541: while ( tt->base == CAST )
1542: tt = tt->e1;
1543: if ( tt->base == ILIST )
1544: e->e1 = tt;
1545:
1546: if (e->e1->base == ILIST) {
1547: // memptr constant
1548: // f({1,2,f}) ==> memptr t; f((t={1,2,f},t))
1549: if(save_base == REF) {
1550: Pptr m = Pptr(a->tp);
1551: error(strict_opt?0:'w',
1552: "address of boundF (try using ``%s::*'' forPT and ``&%s::%s'' for address) (anachronism)",
1553: m->memof->string,
1554: m->memof->string,
1555: save_name
1556: );
1557: }
1558: Pname temp = make_tmp('A',mptr_type,tbl);
1559: e->e1 = mptr_assign(temp,e->e1);
1560: e->e1 = a = new expr(G_CM,e->e1,temp);
1561: a->tp = temp->tp;
1562: }
1563:
1564: }
1565: else {
1566: if (k != ELLIPSIS) {
1567: error("unexpected %dA for%n",argno,fn);
1568: return any_type;
1569: }
1570: Pexpr te=e;
1571: while(e) {
1572: if (e->e1->base == ILIST) {
1573: // memptr constant
1574: // f({1,2,f}) ==> memptr t; f((t={1,2,f},t))
1575: Pname temp = make_tmp('A',mptr_type,tbl);
1576: e->e1 = mptr_assign(temp,e->e1);
1577: e->e1 = a = new expr(G_CM,e->e1,temp);
1578: a->tp = temp->tp;
1579: }
1580: e = e->e2;
1581: }
1582: e = te;
1583: goto rlab;
1584: }
1585: }
1586: else { /* default argument? */
1587: a = nn->n_initializer;
1588: if (a == 0) {
1589: error("A %d ofT%tX for%n",argno,nn->tp,fn);
1590: return any_type;
1591: }
1592: if (a->base == ILIST) {
1593: // memptr constant
1594: // f({1,2,f}) ==> memptr t; f((t={1,2,f},t))
1595: Pname temp = make_tmp('A',mptr_type,tbl);
1596: a = mptr_assign(temp,a);
1597: a = new expr(G_CM,a,temp);
1598: a->tp = temp->tp;
1599: }
1600: a->permanent = 2; // ought not be necessary, but it is
1601: e = new expr(ELIST,a,0);
1602: if (etail)
1603: etail->e2 = e;
1604: else
1605: e2 = e;
1606: etail = e;
1607: }
1608: }
1609:
1610: rlab:
1611: //error('d',"rlab fct_name %n %t",fct_name,fct_name?fct_name->tp:0);
1612: for (; e; e = e->e2) { // unchecked arguments
1613: Pexpr a = e->e1;
1614: Pname cn;
1615:
1616: if (a->base==NAME && a->tp->base==FCT) {
1617: // function name that escaped the type system:
1618: // update use count
1619: a->lval(ADDROF);
1620: }
1621: else if (warning_opt && (cn = a->tp->is_cl_obj())) {
1622: Pclass cl = Pclass(cn->tp);
1623: if (cl->has_ctor() || cl->memtbl->look("__as",0))//cl->has_oper(ASSIGN)
1624: {
1625: if (fct_name)
1626: error('w',"O ofC%t withK or = copied asA to%n (%t)",cl,fct_name,fct_name->tp);
1627: else
1628: error('w',"O ofC%t withK or = copied asA to `...'",cl);
1629: }
1630: }
1631: else if (a->tp->is_ref())
1632: e->e1 = a->contents();
1633: }
1634:
1635: if (f->f_result) { // f(args) => (f(&temp,args),temp)
1636: Pname tn = make_tmp('R',f->returns,tbl);
1637: e2 = new expr(ELIST,tn->address(),e2);
1638: // error('d',"result %n refd: %d",fn, refd);
1639: Pexpr ee = new expr(0,0,0);
1640: *ee = *this;
1641: base = G_CM; // (f(&temp,args),temp)
1642: e1 = ee;
1643: if (refd == 2)
1644: e2 = tn->address();
1645: else e2 = tn;
1646: tp = tn->tp;
1647: }
1648:
1649: return t;
1650: }
1651:
1652: int cm_const_save;
1653:
1654: Pexpr ref_init(Pptr p, Pexpr init, Ptable tbl)
1655: /*
1656: initialize the "p" with the "init"
1657: remember to call ptr_init to ensure that pointers to second bases
1658: are handled correctly.
1659: */
1660: {
1661: register Ptype it = init->tp;
1662: Pptr px = p;
1663: while (px->base == TYPE) px = Pptr(Pbase(px)->b_name->tp);
1664: Ptype p1 = px->typ;
1665: Pname c1 = p1->is_cl_obj();
1666: // error('d',"ref_init: p %t, p1 %t, px %t, init->tp %t",p,p1,px,it);
1667: // error('d', "ref_init: nof: %n f_const: %d", cc?cc->nof:0, cc?(cc->nof?Pfct(cc->nof->tp)->f_const:0):0);
1668:
1669: if (init->base == ILIST) error("IrL as RIr");
1670:
1671: if (init->base==NAME
1672: && Pname(init)->n_scope==ARG
1673: && init->tp->base==FLOAT)
1674: error('w',"initializing a float& with floatA is non-portable");
1675:
1676: while(it->base == TYPE)
1677: it = Pbase(it)->b_name->tp;
1678:
1679: switch (it->base) {
1680: default:
1681: { Ptype tt = it->addrof();
1682: px->base = PTR; // allow &x for y& when y : public x
1683: // but not &char for int&
1684: int x = px->check(tt,COERCE);
1685:
1686: if (x == 0) { //CCC type is fine check for constness:
1687: if (init->tp->tconst()
1688: && vec_const==0
1689: && fct_const==0) {
1690: // not ``it''
1691: if (init->base == ELIST) init = init->e1;
1692: if (px->typ->tconst() == 0) error("R to constO");
1693: px->base = RPTR;
1694: // if we have a const lvalue we can still pass its address
1695: ignore_const++;
1696: if (init->lval(0)) {
1697: init->lval(ADDROF); // force output
1698: ignore_const--;
1699: //error('d',"in1 %t",init->tp);
1700: return ptr_init(px,init->address(),tbl);//return init->address();
1701: }
1702: ignore_const--;
1703: goto xxx;
1704: }
1705: px->base = RPTR;
1706: if (init->lval(0)) { // can pass the address // no temporary needed
1707: init->lval(ADDROF); // force output
1708: //error('d',"px %t init %t init %t",px,init->tp,init->tp);
1709: return ptr_init(px,init->address(),tbl);
1710: }
1711: goto xxx;
1712: }
1713:
1714: px->base = RPTR;
1715: }
1716: }
1717:
1718: //error('d',"c1 %n",c1);
1719: if (c1) { // assigning to a const X & is fine
1720: ref_cast++;
1721: Pexpr x = try_to_coerce(p,init,"reference initialization",tbl);
1722: ref_cast--;
1723: if (x) {
1724: init = x;
1725: goto xxx;
1726: }
1727: while (p1->base==TYPE) p1 = Pbase(p1)->b_name->tp;
1728: int bc = Pbase(p1)->b_const;
1729: Pbase(p1)->b_const = 0;
1730: // refd = 1;
1731: switch ( init->base ) {
1732: case STRING: case ZERO: case CCON:
1733: case ICON: case FCON: case IVAL:
1734: case NAME:
1735: refd = 1;
1736: break;
1737: default:
1738: refd = (init->e1 && init->e1->base == NAME &&
1739: init->e1->tp->base != RPTR &&
1740: Pname(init->e1)->n_xref == 0) ? 2: 1;
1741: break;
1742: }
1743: // error('d', "***** refd: %d", refd );
1744: Pexpr a = class_init(0,p1,init,tbl);
1745: Pbase(p1)->b_const = bc;
1746: refd = 0;
1747: if (a==init && init->tp!=any_type) goto xxx;
1748: // error('d',"ri a %d %k",a->base,a->base);
1749: switch (a->base) {
1750: case G_CALL:
1751: // case CM:
1752: // case G_CM:
1753: init = a;
1754: goto xxx;
1755: }
1756: a = a->address();
1757: a = ptr_init(px,a,tbl);
1758: return a;
1759: // return ptr_init(px,a->address(),tbl);//a->address();
1760: }
1761:
1762: //error('d',"p1 %t it %t",p1,it);
1763: if (p1->check(it,0)) {
1764:
1765: if (p1->check(it,ASSIGN) == 0) {
1766: // if (p1->is_ptr()) // check for base* = derived*
1767: // goto xxx;
1768:
1769: // things like ``double& rr = 1;'' temporary needed
1770: // warn in case of ``slightly wrong lvalue'', e.g.
1771: // int i; double& r = i;
1772: if (init->lval(0) && p1->tconst()==0)
1773: error('w',"temporary used toIR; no changes will be propagated to actualA");
1774: goto def;
1775: }
1776:
1777: Pexpr x = try_to_coerce(p1,init,"reference",tbl); // x==init
1778: if (x==0) x = try_to_coerce(px,init,"reference",tbl); // x&=init
1779: if (x) {
1780: init = x;
1781: goto def;
1782: }
1783:
1784: error("badIrT:%t (%tX)",it,p);
1785: if (init->base != NAME) init->tp = any_type;
1786: return init;
1787: }
1788:
1789: xxx: /*
1790: here comes the test of a ``fundamental theorem'':
1791: a structure valued expression is
1792: (1) an lvalue of type T (possibly const)
1793: or (2) the result of a function (a _result if X(X&) is defined)
1794: or (3) a * or [] or ? or , expression
1795: */
1796: //error('d',"xxx %k %d %t",init->base,init->base,init->tp);
1797:
1798: switch (init->base) {
1799: case NAME:
1800: case DEREF:
1801: case REF:
1802: case DOT: // init => &init
1803: if (it->tconst() && vec_const==0 && fct_const==0) goto def;
1804: if ( cc && cc->nof &&
1805: Pfct(cc->nof->tp)->f_const )
1806: cm_const_save = Pbase(p->typ)->b_const;
1807: init->lval(ADDROF);
1808: cm_const_save = 0;
1809:
1810: if (vec_const) return init;
1811: if (fct_const && p1->is_ptr()) goto def; // fptr& = fct
1812: // no break
1813: case CM:
1814: case G_CM: // & (f(&temp), temp)
1815: return ptr_init(px,init->address(),tbl);//init->address();
1816: default:
1817: def:
1818: {
1819: // error('d',"def: init->tp %t p1 %t ",init->tp,p1);
1820: // error('d',"p1: %t const_ptr: %d", p1, const_ptr);
1821: if (const_ptr == 0) {
1822: if (tbl == gtbl || strict_opt)
1823: error("Ir for%snon-constR not an lvalue", strict_opt?"":" global ");
1824: else
1825: if (warning_opt)
1826: error('w', "Ir for non-constR not an lvalue (anachronism)");
1827: }
1828:
1829: Pname tcl = p1->is_cl_obj ();
1830: if(tcl && Pclass(tcl->tp)->c_abstract)
1831: error("a temporary is needed for a parameter, but the argument type is abstract class %t.", tcl->tp);
1832:
1833: Pname n = make_tmp('I',p1,tbl);
1834: Pexpr a;
1835: Pname ic = init->tp->is_cl_obj();
1836:
1837: if (p1->tconst()==0
1838: && (init->tp->tconst() && vec_const==0 && fct_const==0)
1839: && p1->check(it,ASSIGN)==0)
1840: error('w',"constIr: temporary used toI reference");
1841:
1842: switch (p1->base) {
1843: case INT:
1844: case CHAR:
1845: case SHORT:
1846: switch (it->base) {
1847: case LONG:
1848: case FLOAT:
1849: case DOUBLE:
1850: case LDOUBLE:
1851: error('w',"%t assigned to %t inRIr",it,p1);
1852: }
1853: }
1854:
1855: if (ic!=c1 && Pclass(ic->tp) != Pclass(c1->tp)) {
1856: // derived class1 => must cast: ``it Ix; (Ix=init,(p)&Ix);''
1857: n->tp = init->tp;
1858: a = ptr_init(px,n->address(),tbl);//n->address();
1859: PERM(p);
1860: a = new texpr(CAST,p,a);
1861: a->tp = p;
1862: }
1863: else
1864: a = n->address();
1865:
1866: refd = 1;
1867: Pexpr as = init_tmp(n,init,tbl);
1868: refd = 0;
1869: a = new expr(G_CM,as,a);
1870: a->tp = a->e2->tp;
1871: return a;
1872: }
1873: }
1874: }
1875:
1876: Pexpr class_init(Pexpr nn, Ptype tt, Pexpr init, Ptable tbl)
1877: /*
1878: initialize "nn" of type "tt" with "init"
1879: if nn==0 make a temporary,
1880: nn may not be a name
1881: */
1882: {
1883: if (init == dummy) return 0;
1884: //error('d',"class_init %t with %t init %k refd %d",tt,init->tp,init->base,refd);
1885: Pname c1 = tt->is_cl_obj();
1886:
1887: if (init == 0) {
1888: error("emptyIr");
1889: return dummy;
1890: }
1891:
1892: if (c1) {
1893: Pclass cl = Pclass(c1->tp);
1894: Pname c2 = init->tp->is_cl_obj();
1895:
1896: if (c1!=c2 || (refd==0 && cl->has_itor())) {
1897: /* really ought to make a temp if refd,
1898: but ref_init can do that
1899: */
1900: int i = can_coerce(tt,init->tp);
1901: //error('d',"i %d nn %n",i,nn);
1902: switch (i) {
1903: default:
1904: error("%d ways of making a%n from a%t",i,c1,init->tp);
1905: init->tp = any_type;
1906: return init;
1907: case 0:
1908: if (c2 && Pclass(c2->tp)->has_base(cl)) {
1909: init = init->address();
1910: Pexpr x = cast_cptr(cl,init,tbl,0);
1911:
1912: if (x == init) {
1913: Ptype pt = tt->addrof();
1914: PERM(pt);
1915: x = new cast(pt,init);
1916: }
1917:
1918: return x->contents();
1919: }
1920: error("cannot make a%n from a%t",c1,init->tp);
1921: init->tp = any_type;
1922: return init;
1923: case 1:
1924: //error('d',"ncoerce %n %k %d",Ncoerce,init->base,init->base);
1925: if (Ncoerce == 0) {
1926: Pexpr a = new expr(ELIST,init,0);
1927: a = new texpr(VALUE,tt,a);
1928: a->e2 = nn;
1929: // return a->typ(tbl);
1930: a = a->typ(tbl);
1931: //error('d',"ci a %k %d %t",a->base,a->base,a->tp);
1932: return a;
1933: }
1934:
1935: switch (init->base) {
1936: case CM:
1937: case G_CM: //ddd
1938: case NAME: /* init.coerce() */
1939: /* *ref */ case DEREF:
1940: { Pref r = new ref(DOT,init,Ncoerce);
1941: Pexpr rr = r->typ(tbl);
1942: init = new expr(G_CALL,rr,0);
1943: init->fct_name = Ncoerce;
1944: break;
1945: }
1946: default: // (temp=init,temp.coerce())
1947: { Pname tmp = make_tmp('U',init->tp,tbl);
1948: int x = refd;
1949: refd = 0; // ??
1950: Pexpr ass = init_tmp(tmp,init,tbl);
1951: refd = x;
1952: Pref r = new ref(DOT,tmp,Ncoerce);
1953: Pexpr rr = r->typ(tbl);
1954: Pexpr c = new expr(G_CALL,rr,0);
1955: c->fct_name = Ncoerce;
1956: c = c->typ(tbl);
1957: init = new expr(CM,ass,c);
1958: init->tp = c->tp;
1959: if (refd) { // &f() => (t=f(), &t)
1960: Pname tmp2 = make_tmp('L',c->tp,tbl);
1961: ass = init_tmp(tmp2,init,tbl);
1962: init = new expr(G_CM,ass,tmp2);
1963: }
1964: }
1965: }
1966: //error('d',"nn %n",nn);
1967: if (nn) {
1968: Pexpr a = new expr(ELIST,init,0);
1969: a = new texpr(VALUE,tt,a);
1970: a->e2 = nn;
1971: return a->typ(tbl);
1972: }
1973: }
1974: //error('d',"c1 %n c2 %n",c1,c2);
1975: return init->typ(tbl);
1976: }
1977: return init;
1978: }
1979: //error('d',"ci check tt %t init->tp %t",tt,init->tp);
1980: if (tt->check(init->tp,ASSIGN) && refd==0) {
1981: error("badIrT:%t (%tX)",init->tp,tt);
1982: init->tp = any_type;
1983: }
1984:
1985: return init;
1986: }
1987:
1988: extern int bound; // fudge for bound pointers to functions
1989:
1990: Pexpr expr::docast(Ptable tbl)
1991: {
1992: // check cast against value, INCOMPLETE
1993:
1994: //error('d',"docast %d %t %k",this,tp2,e1->base);
1995: if (e1 == dummy) {
1996: error("E missing for cast");
1997: tp = any_type;
1998: return this;
1999: }
2000:
2001: int pmf = 0;
2002: int ptom_cast = 0;
2003: Pexpr ee = e1;
2004:
2005: //error('d',"ee %k %d",ee->base,ee->base);
2006: switch (ee->base) {
2007: case ADDROF:
2008: ee = ee->e2;
2009: switch (ee->base) {
2010: case NAME: goto nm;
2011: case REF: goto rf;
2012: }
2013: break;
2014:
2015: case NAME:
2016: nm:
2017: if (Pname(ee)->n_qualifier) pmf = 1;
2018: break;
2019:
2020: case REF:
2021: rf:
2022: if (ee->e1->base == THIS) bound = 1;
2023: break;
2024: }
2025:
2026: e1 = e1->typ(tbl);
2027:
2028: int b = bound; // distinguish between explicit and implicit THIS
2029: bound = 0;
2030: pmf = pmf && e1->base==CAST;
2031:
2032: Ptype etp = e1->tp;
2033: Ptype tt = tp2;
2034: Ptype t = tt;
2035: tt->dcl(tbl);
2036:
2037: while (etp->base == TYPE) etp = Pbase(etp)->b_name->tp;
2038: while (tt->base == TYPE) tt = Pbase(tt)->b_name->tp;
2039:
2040: //error('d',"e1 %k etp %t tt %t",e1->base,etp,tt);
2041:
2042: switch (etp->base) {
2043: case PTR:
2044: case RPTR:
2045: if (Pptr(etp)->typ->base == OVERLOAD) goto over;
2046:
2047: if (warning_opt && i2==0 && Pptr(etp)->typ->tconst()) {
2048: switch (tt->base) {
2049: case FCT:
2050: break;
2051: case PTR:
2052: case RPTR:
2053: if (Pptr(tt)->typ->tconst()) break;
2054: default:
2055: // casting away const
2056: // should be an error
2057: // but ANSI says OK so I chicken out
2058: // to be able to compile strtok(), etc.
2059: error('w',"const cast away:%t->%t",e1->tp,tp2);
2060: }
2061: }
2062: else
2063: i2 = 0; // to allow cfront to escape its own checking
2064: break;
2065: case COBJ:
2066: { ref_cast = 1;
2067: Pexpr x = try_to_coerce(tt,e1,"cast",tbl);
2068: ref_cast = 0;
2069: //error('d',"x %k %t tt %d %t",x?x->base:0,x?x->tp:0,tt,tt);
2070: if (x) {
2071: if (x!=e1 && x->base==DEREF && tt->is_ref()) x = x->e1;
2072: if (tt==x->tp || tt->check(x->tp,0)==0 || const_problem)
2073: return x;
2074: else
2075: return new cast(tt,x);
2076: }
2077: // else if (e1->base==DEREF && tt->is_ref()) return e1;
2078: break;
2079: }
2080: case VOID:
2081: if (tt->base == VOID) {
2082: tp = t;
2083: return this;
2084: }
2085: error("cast of void value");
2086: // no break;
2087: case ANY:
2088: any:
2089: tp = any_type;
2090: return this;
2091: case FCT:
2092: if (tt->base == PTR && Pptr(tt)->typ->base != FCT)
2093: error('w',"P toF cast toP to nonF");
2094: break;
2095: case OVERLOAD:
2096: over:
2097: error("cast of overloaded");
2098: goto any;
2099: }
2100:
2101: //error('d',"tt %t",tt);
2102: switch (tt->base) {
2103: case PTR:
2104: if (Pptr(tt)->typ->base==FCT && Pptr(tt)->memof) {
2105: if (etp->base!=PTR
2106: || Pptr(etp)->typ->base!=FCT
2107: || Pptr(etp)->memof==0)
2108: error("cast toP toM %t",tt);
2109: else { // adjust delta in MI case
2110: // for the moment just suppress the cast
2111: // all pmfs are the same to cc
2112: /*
2113: Pclass c1 = Pptr(tt)->memof;
2114: Pclass c2 = Pptr(etp)->memof;
2115: */
2116: ptom_cast = 1;
2117: tp2 = void_type;
2118: }
2119: }
2120:
2121: switch (etp->base) {
2122: case COBJ:
2123: error("cannot castCO toP");
2124: break;
2125: case FCT:
2126: e1 = new expr(G_ADDROF,0,e1);
2127: bound = b;
2128: e1 = e1->typ(tbl);
2129: bound = 0;
2130: if (e1->base == CAST)
2131: pmf = 1;
2132: else
2133: break;
2134: // no break;
2135:
2136: case PTR:
2137: { Pname cn = Pptr(tt)->typ->is_cl_obj();
2138: if (cn) {
2139: Pexpr x = cast_cptr(Pclass(cn->tp),e1,tbl,1);
2140:
2141: if (x == e1) {
2142: PERM(tt);
2143: e1 = new cast(tt,e1);
2144: e1->i2 = i2;
2145: }
2146: else
2147: e1 = x;
2148: }
2149: if (pmf) {
2150: while(tt->base == TYPE)
2151: tt = Pbase(tt)->b_name->tp;
2152:
2153: switch (tt->base) {
2154: case PTR:
2155: if (Pptr(tt)->memof) break;
2156: default:
2157: error("%t cast to%t (%t is not aP toM)",e1->tp,tp2,tp2);
2158: }
2159: }
2160: }
2161: }
2162: break;
2163:
2164: case RPTR: // (x&)e: pretend e is an x
2165: { Ptype er = etp;
2166: Ptype cr = tt;
2167: do {
2168: if (er = er->is_ptr_or_ref()) er = Pptr(er)->typ;
2169: if (cr = cr->is_ptr_or_ref()) cr = Pptr(cr)->typ;
2170: } while (er && cr);
2171: int pp = er!=0; // if `e' is a suitable pointer cast it:
2172: // (x&)e => (x*)e, otherwise
2173: // (x&)e => *(x*)&e
2174: // error('d',"rptr tt %t e1->base %k e1->tp %t",tt,e1->base,e1->tp);
2175: // if (Pptr(tt)->typ->tsizeof()>etp->tsizeof()) goto zse;
2176: // we need to be able to ``raise the type'' from base to derived
2177: // if (etp->is_cl_obj() && Pptr(tt)->typ->is_cl_obj()==0) goto zse;
2178:
2179: if (e1->base==G_CM
2180: || e1->base==CALL
2181: || e1->base==G_CALL
2182: || e1->lval(0))
2183: ;
2184: else if (e1->tp->tconst()) {
2185: // casting away const
2186: // should be an error
2187: // but ANSI says OK so I chicken out
2188: // to be able to compile strtok(), etc.
2189: if (warning_opt && Pptr(tt)->typ->tconst()==0)
2190: error('w',"const cast away:%t->%t",e1->tp,tp2);
2191:
2192: }
2193: else
2194: error("cannot cast%t to%t",etp,t);
2195: //error('d',"e1 %k %t %d",e1->base,e1->tp,pp);
2196: if (pp == 0) e1 = e1->address(); // *(x*)&e
2197: tp = t;
2198:
2199: // do proper pointer manipulation for multiple inheritance
2200: Pname cn = Pptr(tt)->typ->is_cl_obj();
2201: if (cn) {
2202: Pexpr x = cast_cptr(Pclass(cn->tp),e1,tbl,1);
2203:
2204: if (x == e1) {
2205: PERM(tt);
2206: e1 = new cast(tt,e1);
2207: e1->i2 = i2;
2208: }
2209: else
2210: e1 = x;
2211: }
2212:
2213: return pp ? this : contents();
2214: // zse:
2215: // error("cannot cast%t to%t",etp,t);
2216: // tp2 = tt = any_type;
2217: // break;
2218: }
2219: case COBJ:
2220: base = VALUE; // (x)e => x(e): construct an x from e
2221: e1 = new expr(ELIST,e1,0);
2222: return typ(tbl);
2223:
2224: case CHAR:
2225: case INT:
2226: case SHORT:
2227: case LONG:
2228: switch (etp->base) {
2229: case FCT:
2230: e1 = new expr(ADDROF,0,e1);
2231: e1 = e1->typ(tbl);
2232: //etp = e1->tp;
2233: case PTR:
2234: if(!e1->tp->memptr() && e1->tp->tsizeof()>tt->tsizeof())
2235: error("type ``%t'' not large enough for values of ``%t ''",tt,etp);
2236: break;
2237: case COBJ:
2238: error("cannot castCO to%k",tt->base);
2239: break;
2240: }
2241: break;
2242:
2243: case FLOAT:
2244: case DOUBLE:
2245: case LDOUBLE:
2246: switch (etp->base) {
2247: case FLOAT:
2248: case DOUBLE:
2249: case LDOUBLE:
2250: case CHAR:
2251: case INT:
2252: case SHORT:
2253: case LONG:
2254: case EOBJ:
2255: case ZTYPE:
2256: break;
2257: default:
2258: error("cannot cast ``%t '' to ``%t''",etp,tt);
2259: break;
2260: }
2261: break;
2262:
2263: case FCT:
2264: error("cannot cast toFT");
2265: break;
2266: }
2267:
2268: tp = t;
2269:
2270: if (e1->base==ILIST && ptom_cast==0) { // pointer to member constant
2271: Pexpr ee = e1->e1; // ELIST
2272: int i;
2273: switch (ee->e2->base) {
2274: case IVAL:
2275: i = int(ee->e2->i1);
2276: break;
2277: case ZERO:
2278: i = 0;
2279: }
2280:
2281: if (i<0)
2282: e1 = e1->e2; // just the function
2283: else
2284: e1 = ee->e2; // just the index
2285: return this;
2286: }
2287:
2288: if (etp->base==PTR && Pptr(etp)->memof && Pptr(etp)->typ->base==FCT) {
2289: Pclass cl = Pptr(etp)->memof;
2290:
2291: if (Pptr(tt)->memof==0 && b == 0 ) {
2292: Pexpr y = new mdot("f",e1);
2293: y->i1 = 9;
2294: y = new cast(tt,y);
2295: if (cl->virt_count && b==0) {
2296: // ERROR: no check for side effects
2297: Pexpr z = new mdot("i",e1);
2298: Pexpr x = new mdot("i",e1);
2299: x->i1 = 9;
2300: x = new cast(tt,x);
2301: z->i1 = 9;
2302: Pexpr q = new expr (QUEST,x,y);
2303: q->cond = new expr(LE,zero,z);
2304: q->tp = tt;
2305: delete this;
2306: return q;
2307: }
2308: delete this;
2309: return y;
2310: }
2311: }
2312:
2313: return this;
2314: }
2315:
2316: Pexpr expr::dovalue(Ptable tbl)
2317: {
2318: Ptype tt = tp2;
2319: Pclass cl;
2320: Pname cn;
2321:
2322: //error('d',"value %d %t e1 %d e2 %d",tt,tt,e1,e2);
2323:
2324: tt->dcl(tbl);
2325:
2326: while(tt->base == TYPE)
2327: tt = Pbase(tt)->b_name->tp;
2328:
2329: switch (tt->base) {
2330: case EOBJ:
2331: default:
2332: if (e1 == 0) {
2333: error("value missing in conversion to%t",tt);
2334: return dummy;
2335: }
2336: base = CAST;
2337: e1 = e1->e1; // strip ELIST
2338: return typ(tbl);
2339:
2340: case CLASS:
2341: cl = Pclass(tt);
2342: tp2 = Pptr(cl->this_type)->typ;
2343: break;
2344:
2345: case COBJ:
2346: cn = Pbase(tt)->b_name;
2347: cl = Pclass(cn->tp);
2348: }
2349:
2350: //error('d',"e1 %k e1->e2 %k",e1->base,e1?e1->e2->base:0);
2351: if (e1 && e1->e2==0) { // single argument
2352: if (e1->e1->base==ELIST) e1->e1 = e1->e1->e1; // spurious elist
2353: e1->e1 = e1->e1->typ(tbl);
2354: if (tt->base==COBJ) {
2355: Pexpr x = try_to_coerce(tt,e1->e1,"type conversion",tbl);
2356: if (x) return x;
2357: }
2358:
2359: Pname acn = e1->e1->tp->is_cl_obj();
2360: //error('d',"acn %n %d",acn,cl->has_itor());
2361: if (acn && cl->has_itor()==0) {
2362: Pclass acl = Pclass(acn->tp);
2363: int hb = acl->has_base(cl);
2364:
2365: if (acl==cl || hb) {
2366: vcllist->clear();
2367: vcllist=0;
2368: if (1<is_unique_base(acl,cl->string,0)) error("ambiguous assignment to base %t",cl);
2369: Pexpr ee = e1->e1;
2370: if (ee->base == ELIST) ee = ee->e1; // ???
2371: if (hb) { // ee => *(tp2*)&ee
2372: // remember = may be overloaded
2373: //error('d',"hb %k %t %d",ee->base,ee->tp,ee->lval(0));
2374: ignore_const++;
2375: if (ee->lval(0)==0) {
2376: Pname tmp = make_tmp('T',ee->tp,tbl);
2377: ee = init_tmp(tmp,ee,tbl);
2378: ee = new expr(G_CM,ee,tmp->address());
2379: }
2380: else
2381: ee = ee->address();
2382: ignore_const--;
2383: ee = new texpr(CAST,new ptr(PTR,tp2),ee); //new cast(new ptr(PTR,tp2),ee);
2384: ee = ee->contents();
2385: ee->typ(tbl);
2386: }
2387:
2388: if (e2) { // x(x_obj) => e2=x_obj
2389: base = ASSIGN;
2390: e1 = e2;
2391: e2 = ee;
2392: tp = tp2;
2393: return this;
2394: }
2395: return ee; // strip ELIST: x(x_obj) => x_obj
2396: }
2397: }
2398: }
2399:
2400:
2401: /* x(a) => obj.ctor(a); where e1==obj */
2402: Pname ctor = cl->has_ctor();
2403: if (ctor == 0) {
2404: error("cannot make a%t",cl);
2405: return dummy;
2406: }
2407:
2408: // error('d',"e2 %k",e2?e2->base:0);
2409: // error('d',"refd: %d const_ptr: %d", refd, const_ptr);
2410: if (e2 == 0) { // x(a) => x temp; (temp.x(a),temp)
2411: /* incomplete condition
2412: if ( refd && const_ptr == 0) {
2413: if ( tbl == gtbl ) {
2414: error("Ir forG non-constCR not an lvalue");
2415: }
2416: else
2417: if (strict_opt)
2418: error("Ir for non-constCR not an lvalue");
2419: else
2420: if (warning_opt)
2421: error('w', "Ir for non-constR not an lvalue (anachronism)");
2422: }
2423: */
2424:
2425: no_sti = 1;
2426: Pname n = make_tmp('V',tp2,tbl);
2427: no_sti = 0;
2428: n->assign();
2429: if (tbl == gtbl) n->dcl_print(0); // a hack
2430: Pexpr c = call_ctor(tbl,n,ctor,e1,DOT);
2431: c = new expr(G_CM,c,n);
2432: c->tp = n->tp;
2433: //error('d',"tp1 %t",c->tp);
2434: return c;
2435: }
2436: else {
2437: Pexpr c = call_ctor(tbl,e2,ctor,e1,DOT);
2438: c = new expr(DEREF,c,0); // deref value returned by constructor
2439: c->tp = c->e1->tp;
2440: //error('d',"tp2 %t",c->tp);
2441: return c;
2442: }
2443: }
2444:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.