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