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