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