|
|
1.1 root 1: /*ident "@(#)ctrans:src/expr3.c 1.3.5.29" */
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:
631: /* look for constructor
632: with one argument
633: or with default for second argument
634: of acceptable type
635: */
636: Pname ctor = cl->has_ctor();
637: if (ctor == 0) goto oper_coerce;
638: register Pfct f = Pfct(ctor->tp);
639: //error('d',"ctor %n f %t",ctor,f);
640: switch (f->base) {
641: case FCT:
642: switch (f->nargs) {
643: case 1:
644: one:
645: { Ptype tt = f->argtype->tp;
646: //error('d',"tt %t t2 %t -> %d cp %d",tt,t2,tt->check(t2,COERCE),const_problem);
647: if (tt->check(t2,COERCE)==0)
648: val = 1;
649: else if (const_problem) {
650: Pptr p1 = tt->is_ptr_or_ref();
651: if (p1==0 || p1->typ->tconst()) val = 1;
652: }
653: if (tt = tt->is_ref()) {
654: Pptr pt = t2->addrof(); // handle derived classed
655: tt->base = PTR;
656: if (tt->check(pt,COERCE) == 0) val = 1;
657: tt->base = RPTR;
658: delete pt;
659: }
660: goto oper_coerce;
661: }
662: default:
663: if (f->argtype->n_list->n_initializer) goto one;
664: case 0:
665: goto oper_coerce;
666: }
667: case OVERLOAD:
668: { register Plist gl;
669:
670: for (gl=Pgen(f)->fct_list; gl; gl=gl->l) { // look for match
671: Pname nn = gl->f;
672: Pfct ff = Pfct(nn->tp);
673:
674: switch (ff->nargs) {
675: case 0:
676: break;
677: case 1:
678: over_one:
679: { Ptype tt = ff->argtype->tp;
680: //error('d',"over one %t %t -> %d %d",tt,t2,tt->check(t2,COERCE),const_problem);
681: if (tt->check(t2,COERCE)==0)
682: val = 1;
683: else if (const_problem) {
684: Pptr p1 = tt->is_ptr_or_ref();
685: if (p1==0 || p1->typ->tconst()) val = 1;
686: }
687: if (tt=tt->is_ref()) {
688: Pptr pt = t2->addrof(); // handle derived classed
689: tt->base = PTR;
690: if (tt->check(pt,COERCE) == 0) {
691: tt->base = RPTR;
692: delete pt;
693: val = 1;
694: goto oper_coerce;
695: }
696: tt->base = RPTR;
697: delete pt;
698: }
699: break;
700: }
701: default:
702: if (ff->argtype->n_list->n_initializer) goto over_one;
703: }
704: }
705: goto oper_coerce;
706: }
707: default:
708: error('i',"cannot_coerce(%k)\n",f->base);
709: }
710: }
711:
712: oper_coerce:
713: //error('d',"oper_coerce %d",val);
714: if (c2) {
715: Pclass cl = Pclass(c2->tp);
716: int std = 0;
717: int oval = val;
718: extern Pname conv_dominates(Pname,Pname);
719: for (Pname ox, on=cl->conv; on; on=ox) {
720: Pfct f = Pfct(on->tp);
721: ox = on->n_list;
722: Nstd = 0;
723: //error('d',"on %n -> %d",on,t1->check(f->returns,COERCE));
724: if (t1->check(f->returns,COERCE) == 0) {
725: if (Nstd==0) { // forget solutions involving standard conversions
726: Pname old = Ncoerce;
727: if (std) { // forget
728: val = oval+1;
729: std = 0;
730: Ncoerce = on;
731: }
732: else if (Ncoerce == 0) {
733: // val = 1;
734: val++;
735: Ncoerce = on;
736: }
737: else if ((Ncoerce = conv_dominates(Ncoerce,on))==0) {
738: if (val == 1) {
739: //error('d',"val==1 on %n old %n",on,old);
740: Ptype ton = Pfct(on->tp)->returns;
741: Ptype tco = Pfct(old->tp)->returns;
742: if (t1->check(ton,0)==0)
743: ;
744: else if (t1->check(tco,0)==0)
745: on = old;
746: else
747: val++;
748: }
749: else
750: val++;
751: Ncoerce = on;
752: }
753: }
754: else { // take note only if no exact match seen
755: if (Ncoerce==0 || on->tp->check(Ncoerce->tp,0)) {
756: if (val==0 || std) {
757:
758: if (Ncoerce) Ncoerce = conv_dominates(Ncoerce,on);
759: if (Ncoerce == 0) {
760: Ncoerce = on;
761: val++;
762: std = 1;
763: }
764: }
765: }
766: }
767: }
768:
769: }
770: }
771: //error('d',"val %d",val);
772: if (val) return val;
773: if (c1 && Pclass(c1->tp)->has_itor()) return 0;
774: //error('d',"%t->check(%t) -> %d",t1,t2,t1->check(t2,COERCE));
775: if (t1->check(t2,COERCE)) return 0;
776: return 1;
777: }
778:
779: int gen_coerce(Pname n, Pexpr arg)
780: /*
781: look to see if the argument list "arg" can be coerced into a call of "n"
782: 1: it can
783: 0: it cannot or it can be done in more than one way
784: */
785: {
786: Pfct f = (Pfct) n->tp;
787: register Pexpr e;
788: register Pname nn;
789:
790: //error('d',"gen_coerce(%n,%d) %t",n,arg,n->tp);
791: for (e=arg, nn=f->argtype; e; e=e->e2, nn=nn->n_list) {
792: if (nn == 0) return f->nargs_known==ELLIPSIS;
793: Pexpr a = e->e1;
794: Ptype at = a->tp;
795: int i = can_coerce(nn->tp,at);
796: //error('d',"i %d",i);
797: if (i != 1) return 0;
798: }
799: if (nn && nn->n_initializer==0) return 0;
800: return 1;
801: }
802:
803:
804: Pname Nover;
805: // int Nover_coerce;
806:
807: int over_call(Pname n, Pexpr arg)
808: /*
809: return 4 if n(arg) can be performed without coercion of arg
810: return 3 if n(arg) can be performed only with promotion coercion of arg
811: return 2 if n(arg) can be performed only with standard coercion of arg
812: return 1 if n(arg) can be performed only with user defined coercion of arg
813: return 0 if n(arg) is an error
814: Nover is the function found, if any
815: Nstd is the number of standard coercions used
816: */
817: {
818: register Plist gl;
819: Pgen g = Pgen(n->tp);
820: if (arg && arg->base!= ELIST) error('i',"ALX");
821:
822: //error('d',"over_call(%n) %k",n,n->tp->base);
823: extern suppress_error;
824: suppress_error = 1;
825: // Nover_coerce = 0;
826: Nstd = 0;
827: switch (g->base) {
828: default: error('i',"over_call(%t)\n",g);
829: case OVERLOAD: break;
830: case FCT:
831: Nover = n;
832: Ninit = 0;
833: if (exact_match(n,arg)) {suppress_error = 0; return 4;}
834: if (prom_match(n,arg)) {suppress_error = 0; return 3;}
835: if (std_match(n,arg) && Ninit==0) {suppress_error = 0; return 2;}
836: Nstd = 0;
837: suppress_error = 0;
838: return gen_coerce(n,arg);
839: }
840:
841: Pname exact = 0;
842: int no_exact = 0;
843: int ret = 0;
844: Pname nret;
845: for (gl=g->fct_list; gl; gl=gl->l) { /* look for match */
846: Nover = gl->f;
847: Ninit = 0;
848: Nstd = 0;
849: if (exact_match(Nover,arg)) {suppress_error = 0; return 4;} // no coercion
850: // if (prom_match(Nover,arg)) return 3; // only promotion
851: // if (std_match(Nover,arg) && Ninit==0) return 2; // only built-in conversion
852: if (ret<3 && prom_match(Nover,arg)) {
853: nret = Nover;
854: ret = 3;
855: }
856: if (ret<2 && std_match(Nover,arg) && Ninit==0) {
857: nret = Nover;
858: ret = 2;
859: }
860: }
861:
862: suppress_error = 0;
863: if (ret) {
864: Nover = nret;
865: return ret;
866: }
867:
868: Nover = 0;
869: for (gl=g->fct_list; gl; gl=gl->l) { /* look for coercion */
870: Pname nn = gl->f;
871: if (gen_coerce(nn,arg)) {
872: Nover = nn;
873: return 1;
874: }
875: }
876: return 0;
877:
878: }
879:
880: Ptype expr::call_fct(Ptable tbl)
881: /*
882: check "this" call:
883: e1(e2)
884: e1->typ() and e2->typ() has been done
885: */
886: {
887: Pfct f;
888: Pname fn;
889: int x;
890: int k;
891: Pname nn;
892: Pexpr e;
893: Ptype t;
894: Pexpr arg = e2;
895: Ptype t1 = e1?e1->tp:0;
896: int argno;
897: Pexpr etail = 0;
898: Pname no_virt = 0; // set if explicit qualifier was used: c::f()
899: Pname chk = 0; // set if visibility check is needed
900: // that is if function name might have been
901: // found without use of find_name()
902: int const_obj = 0;
903:
904: if (t1 == any_type) return any_type;
905:
906: switch (base) {
907: case CALL:
908: case G_CALL: break;
909: default: error('i',"call_fct(%k)",base);
910: }
911:
912: //error('d',"call %d %k %n arg %d",this,e1->base,e1->base==NAME?e1:0,arg);
913: if (t1 == 0) error('i',"call_fct(e1=%d,e1->tp=%t)",e1,t1);
914: if (arg && arg->base!=ELIST) error('i',"badAL%d%k",arg,arg->base);
915:
916: switch (e1->base) {
917: case NAME:
918: fn = Pname(e1);
919: //error('d',"name %n %k",fn,fn->n_oper);
920: switch (fn->n_oper) {
921: case 0:
922: case CTOR:
923: case DTOR:
924: case TYPE:
925: case NEW:
926: case DELETE:
927: break;
928: default: // real operator: check for operator+(1,2);
929: if (arg == 0) break;
930: Pexpr a = arg->e1; // first operand
931:
932: if (Pfct(fn->tp)->memof // obj.operator(1) is OK
933: || a->tp->is_cl_obj()
934: || a->tp->is_ref()) break;
935: a = arg->e2;
936: if (a == 0) // unary
937: error("%k of basicT",fn->n_oper);
938: else { // binary
939: a = a->e1; // second operand
940: if (a->tp->is_cl_obj() || a->tp->is_ref()) break;
941: error("%k of basicTs",fn->n_oper);
942: }
943: break;
944: }
945: break;
946: case REF:
947: case DOT:
948: no_virt = Pname(e1->n_initializer);
949: e1->n_initializer = 0;
950: // const_obj = (e1&&e1->e1)?e1->e1->tp->tconst():0;
951: if (e1 && e1->e1) {
952: Ptype t = e1->e1->tp;
953: Pptr tt = t->is_ptr_or_ref();
954: //error('d',"t %t tt %t",t,tt);
955: const_obj = (tt ? tt->typ : t)->tconst();
956: }
957: case MDOT:
958: { Pexpr n = e1->mem;
959: lxlx:
960: switch (n->base) {
961: case MDOT:
962: // reverse mdot (see expr::print())
963: // p->a.b() => (&p->a)->b() => b(&p->a)
964: // or p->a->b() => (p->a)->b() => b(p->a)
965: // or oo.a.b() => (&oo.a)->b() => b(&oo.a)
966: // or oo.a->b() => (oo.a)->b() => b(oo.a)
967: {
968: Pexpr r = e1;
969: Pexpr p = r->e1;
970: for (Pexpr m = r->mem; m->base==MDOT; m = r->mem) {
971: p = new mdot(m->string2,p);
972: p->i1 = m->i1+2;
973: p->tp = p->mem->tp;
974: r->mem = m->mem;
975: r->e1 = p;
976: }
977: }
978: case REF:
979: case DOT:
980: n = n->mem;
981: goto lxlx;
982: case NAME:
983: break;
984: default:
985: error('i',"ref %k",n->base);
986: }
987: fn = Pname(n);
988: //error('d',"mem %n",fn);
989: break;
990: }
991: case MEMPTR:
992: default:
993: fn = 0;
994: };
995:
996: lll:
997: //error('d',"lll: %t %k",t1,t1->base);
998: switch (t1->base) {
999: case TYPE:
1000: t1 = Pbase(t1)->b_name->tp;
1001: goto lll;
1002:
1003: case PTR: // pf() allowed as shorthand for (*pf)()
1004: switch (Pptr(t1)->typ->base) {
1005: case FCT:
1006: case OVERLOAD:
1007: if (Pptr(t1)->memof) error("O missing in call throughP toMF");
1008: t1 = Pptr(t1)->typ;
1009: fn = 0;
1010: goto lll;
1011: }
1012:
1013: default:
1014: if (fn)
1015: error("call of%n;%n is a%t",fn,fn,e1->tp);
1016: else
1017: error("call of%kE ofT%t",e1->base,e1->tp);
1018:
1019: case ANY:
1020: return any_type;
1021:
1022: case OVERLOAD:
1023: { register Plist gl;
1024: Pgen g = Pgen(t1);
1025: Pname found = 0;
1026: Pname exact = 0;
1027: int no_exact = 0;
1028:
1029: for (gl=g->fct_list; gl; gl=gl->l) { // look for exact match
1030: register Pname nn = gl->f;
1031: if (exact_match(nn,arg)) {
1032: //error('d',"found exact %n %t",nn,nn->tp);
1033: if (found) {
1034: // check if one fct dominates the other
1035: Pname d = dominate(found,nn,arg,const_obj,0);
1036: if (d)
1037: nn = d;
1038: else
1039: error("two exact matches for%n:%t and%t",nn,nn->tp,found->tp);
1040: }
1041: found = nn;
1042: }
1043: }
1044: //error('d',"found exact2 %n",found);
1045: if (found) goto fnd;
1046:
1047: for (gl=g->fct_list; gl; gl=gl->l) { // look for exact match
1048: register Pname nn = gl->f;
1049:
1050: if (prom_match(nn,arg)) {
1051: if (found) {
1052: // check if one fct dominates the other
1053: Pname d = dominate(found,nn,arg,const_obj,1);
1054: if (d)
1055: nn = d;
1056: else
1057: error("two exact matches (after integral promotions) for%n:%t and%t",nn,nn->tp,found->tp);
1058: }
1059: found = nn;
1060: }
1061: }
1062: //error('d',"found exact2 %n",found);
1063: if (found) goto fnd;
1064:
1065: // for (gl=g->fct_list; gl; gl=gl->l) { // look for exact match
1066: // register Pname nn = gl->f;
1067: //
1068: // if (exact_match(nn,arg) || prom_match(nn,arg)) {
1069: // found = nn;
1070: // goto fnd;
1071: // }
1072: // }
1073:
1074: Pname mvec[10];
1075: for (gl=g->fct_list; gl; gl=gl->l) { // look for match
1076: // with standard conversion
1077: register Pname nn = gl->f;
1078: Ninit = 0;
1079: Nstd = 0;
1080: if (std_match(nn,arg)) {
1081: // if (Nstd == 0) {
1082: // found = nn;
1083: // goto fnd;
1084: // }
1085: if (exact) {
1086: // check if one fct dominates the other
1087: Pname d = dominate(exact,nn,arg,const_obj,2);
1088: if (d == 0) {
1089: mvec[no_exact++] = nn;
1090: // no_exact++;
1091: // error("two standard conversions possible for%n: %t and %t",fn,exact->tp,nn->tp);
1092: }
1093: else
1094: exact = d;
1095: }
1096: else
1097: exact = nn;
1098: }
1099:
1100: }
1101:
1102: //error('d',"excact %n",exact);
1103: if (exact) {
1104: if (no_exact) {
1105: while (no_exact) {
1106: Pname d = dominate(exact,mvec[--no_exact],arg,const_obj,2);
1107: if (d)
1108: exact = d;
1109: else
1110: error("two standard conversions possible for%n: %t and %t",fn,exact->tp,mvec[no_exact]->tp);
1111: }
1112:
1113: }
1114: //error('d',"found exact3 %n",found);
1115: found = exact;
1116: goto fnd;
1117: }
1118:
1119: for (gl=g->fct_list; gl; gl=gl->l) { /* look for coercion */
1120: register Pname nn = gl->f;
1121: if (gen_coerce(nn,arg)) {
1122: //error('d',"user2 %n %t",nn,nn->tp);
1123: if (found) {
1124: // check if one fct dominates the other
1125: Pname d = dominate(found,nn,arg,const_obj,3);
1126: if (d == 0) d = user_dominate(found,nn);
1127: if (d == 0) {
1128: error("ambiguousA for%n: %t and %t",fn,found->tp,nn->tp);
1129: goto fnd;
1130: }
1131: else
1132: found = d;
1133: }
1134: else
1135: found = nn;
1136: }
1137: }
1138:
1139: fnd:
1140: //error('d',"fnd %t",found?found->tp:0);
1141: if (found) {
1142: chk = fn = found;
1143: f = Pfct(fn->tp);
1144: }
1145: else {
1146: error("badAL for%n (no match against any %n)",fn,fn);
1147: return any_type;
1148: }
1149: break;
1150: }
1151: case FCT:
1152: f = Pfct(t1);
1153: if (fn) {
1154: switch (fn->n_oper) {
1155: case CTOR:
1156: case TYPE:
1157: chk = fn;
1158: }
1159: }
1160: }
1161:
1162: //error('d',"chk %n",chk);
1163: if (chk) {
1164: Ptype t = 0;
1165: Pexpr ee = e1->e1;
1166:
1167: switch (e1->base) {
1168: case REF: // ptr->chk()
1169: if (ee == 0) { // 0->x() fudge handling new x()
1170: check_visibility(chk,no_virt,Pclass(chk->n_table->t_name->tp),tbl,cc->nof);
1171: break;
1172: };
1173: t = ee->tp;
1174: while(t->base==TYPE) t = Pbase(t)->b_name->tp;
1175: t = Pptr(t)->typ;
1176: break;
1177: case DOT: // obj.chk()
1178: t = ee->tp;
1179: }
1180:
1181: Pname cn = t?t->is_cl_obj():0;
1182: Pclass cl = cn?Pclass(cn->tp):0; // class of ``this'' for chk
1183:
1184: if (cl) {
1185: if (chk->n_oper==CTOR
1186: && chk->n_protect
1187: && cc->nof
1188: && cc->nof->n_oper==CTOR)
1189: // BUG: cannot handle protected base
1190: // class constructor
1191: ;
1192: else {
1193: check_visibility(chk,no_virt,cl,tbl,cc->nof);
1194: }
1195: }
1196: }
1197:
1198: if (fn && f->f_result==0) {
1199: // protect against class cn; cn f(); ... class cn { cn(cn&); ... };
1200: make_res(f);
1201: //error('d',"returns %t",f->returns);
1202: f->returns->tsizeof(); // make sure it is declared
1203: }
1204:
1205: //error('d',"fn %n %t printed %d",fn,fn?fn->tp:0,fn?fn->n_dcl_printed:0);
1206: if (fn && fn->n_dcl_printed==0) {
1207: if (f->f_inline==0 && f->f_imeasure) {
1208: extern void uninline(Pname fn);
1209: uninline(fn);
1210: }
1211:
1212: // ensure printout of class declaration:
1213: for (Pname nn=f->argtype; nn; nn=nn->n_list)
1214: if (nn->tp->is_cl_obj()) (void) nn->tp->tsizeof();
1215:
1216: fn->dcl_print(0);
1217: }
1218:
1219: if (no_virt && f->f_static==0) {
1220: if (e1->base==REF || e1->base==DOT) e1->n_initializer = fn;
1221: }
1222: else
1223: fct_name = fn;
1224: //error('d',"fn %n %t %d %d",fn,f,f->f_this,f->f_static);
1225: if (f->f_this) { //SSS call of non-static memberfunction
1226: switch (e1->base) {
1227: case MEMPTR:
1228: case REF:
1229: case DOT:
1230: break;
1231: default:
1232: error("O orP missing for%n ofT %t",fct_name,f);
1233: }
1234: }
1235: else if (fn) { //SSS call of static function
1236: sss:
1237: switch (e1->base) {
1238: case REF:
1239: case DOT:
1240: e1 = e1->mem;
1241: goto sss;
1242: }
1243: }
1244:
1245: if (fn) fn->use(); // a patch: ctors are sometimes not use()d
1246:
1247: if (f->f_const==0
1248: && (fn==0 || (fn->n_oper!=CTOR && fn->n_oper!=DTOR))) { //CCC
1249: Pexpr ee = e1->e1;
1250: if (ee) {
1251: Ptype tt = ee->tp;
1252: switch (e1->base) {
1253: case REF:
1254: { Pptr p = tt?tt->is_ptr():0;
1255: if (p && p->typ->tconst())
1256: error(strict_opt?0:'w',"non-constMF%n called for constO",fn);
1257: // is really an error, but only warn to help transition
1258: break;
1259: }
1260: case DOT:
1261: if (tt && tt->tconst())
1262: error(strict_opt?0:'w',"non-constMF%n called for constO",fn);
1263: // is really an error, but only warn to help transition
1264: }
1265: }
1266: }
1267:
1268: t = f->returns;
1269: x = f->nargs;
1270: k = f->nargs_known;
1271:
1272: e = arg;
1273: if (k == 0) goto rlab;
1274:
1275: for (nn=f->argtype, argno=1; e||nn; nn=nn->n_list, e=etail->e2, argno++) {
1276: Pexpr a;
1277:
1278: if (e) {
1279: a = e->e1;
1280: etail = e;
1281:
1282: if (nn) { /* type check */
1283: Ptype t1 = nn->tp;
1284: //error('d',"argtp %t etp %t a %k",t1,a->tp,a->base);
1285:
1286: lx:
1287: switch (t1->base) {
1288: case TYPE:
1289: t1 = Pbase(t1)->b_name->tp;
1290: goto lx;
1291: case RPTR:
1292: { Ptype pt = Pptr(t1)->typ;
1293: if (pt->base != FCT ||
1294: ( pt->base == FCT &&
1295: pt->check(a->tp,0)))
1296: a = ref_init(Pptr(nn->tp),a,tbl);
1297: goto cbcb;
1298: }
1299: case COBJ:
1300: if (a->base!=G_CM
1301: || nn->tp->check(a->tp,ASSIGN))
1302: a = class_init(0,t1,a,tbl);
1303: if (nn->n_xref) {
1304: // (temp.ctor(arg),&arg)
1305: a = a->address();
1306: }
1307: else {
1308: // defend against:
1309: // int f(X); ... X(X&);
1310: Pname cln = Pbase(t1)->b_name;
1311: if (cln && Pclass(cln->tp)->has_itor()) {
1312: // mark X(X&) arguments
1313: nn->n_xref = 1;
1314: a = a->address();
1315: }
1316: }
1317: cbcb:
1318: //error('d',"cbcb: a %d %k %t",a->base,a->base,a->tp);
1319: if (a->base==G_CM) {
1320: if (a->e1->base==DEREF) a->e1 = a->e1->e2; // (*e1,e2) => (e1,e2)
1321: //error('d'," a %d %k",a->e1->base,a->e1->base);
1322: if (a->e1->base==G_CALL
1323: && Pname(a->e1->fct_name)
1324: && Pname(a->e1->fct_name)->n_oper==CTOR
1325: && (a->e2->base==G_ADDROF || a->e2->base==ADDROF)) {
1326: a = a->e1; // (ctor(&tmp),&tmp) => ctor(&tmp)
1327: //error('d',"tmp %k %n",a->e2->base,a->e2->e2);
1328: goto cccc;
1329: }
1330: else if (a->e2->base==G_ADDROF
1331: && a->e2->e2->base==NAME) {
1332: cccc:
1333: //error('d',"cccc: a %d %k %t",a->base,a->base,a->tp);
1334: if (t1->base==RPTR
1335: && Pptr(t1)->typ->tconst()==0) { // temporary used
1336: if (warning_opt)
1337: error('w',"temporary used for non-const%tA",nn->tp);
1338: else {
1339: Ptype atp = a->tp;
1340: if (atp==void_type
1341: && a->base==G_CALL
1342: && a->e1->tp->base==FCT)
1343: atp = Pfct(a->e1->tp)->s_returns;
1344:
1345: Ptype tt = t1->is_ref();
1346: //error('d',"tt %t atp %t",tt,atp);
1347: if (tt) {
1348: if (Pptr(tt)->typ->tsizeof()!=atp->tsizeof()) { // sliced
1349: Ptype aat = atp->is_ptr_or_ref();
1350: if (aat==0
1351: || Pptr(tt)->typ->tsizeof()!=Pptr(aat)->typ->tsizeof())
1352: error('w',"temporary used for non-const%tA",nn->tp);
1353: }
1354: }
1355: else if (t1->tsizeof()!=atp->tsizeof()) // sliced
1356: error('w',"temporary used for non-const%tA",nn->tp);
1357: }
1358:
1359: // if (warning_opt // blabber
1360: // || t1->tsizeof()!=a->tp->tsizeof())) // sliced
1361: // error('w',"temporary used for non-const%tA",nn->tp);
1362:
1363: }
1364: }
1365: }
1366: e->e1 = a;
1367: break;
1368: case ANY:
1369: goto rlab;
1370: case PTR:
1371: {// Pexpr x = a;
1372: e->e1/* = a */= ptr_init(Pptr(t1),a,tbl);
1373: // if (x==a || x==a->e2) goto def; // needs checking
1374: if (Pchecked == 0) goto def;
1375: break;
1376: }
1377: // e->e1 = a = ptr_init(Pptr(t1),a,tbl);
1378: // goto def;
1379: case CHAR:
1380: case SHORT:
1381: case INT:
1382: // if (a->base==ICON && a->tp==long_type)
1383: // error('w',"long constantA for%n,%kX",fn,t1->base);
1384: { Ptype t = a->tp;
1385: csi:
1386: switch (t->base) {
1387: case TYPE:
1388: t = Pbase(t)->b_name->tp; goto csi;
1389: case LONG:
1390: case FLOAT:
1391: case DOUBLE:
1392: case LDOUBLE:
1393: error('w',"%t passed as %t",a->tp,t1);
1394: }
1395: }
1396: // no break
1397: case LONG:
1398: if (Pbase(t1)->b_unsigned
1399: && a->base==UMINUS
1400: && a->e2->base==ICON)
1401: error('w',"negativeA for%n, unsignedX",fn);
1402: default:
1403: def:
1404: { Pexpr x = try_to_coerce(t1,a,"argument",tbl);
1405: //error('d',"x %d t1 %t nn %t a1 %t",x,t1,nn->tp,a->tp);
1406: if (x)
1407: e->e1 = x;
1408: else if (nn->tp->check(a->tp,ARG)) {
1409: error("badA %dT for%n:%t (%tX)",argno,fn,a->tp,nn->tp);
1410: return any_type;
1411: }
1412: }
1413: }
1414:
1415: Pexpr tt = e->e1;
1416: while ( tt->base == CAST )
1417: tt = tt->e1;
1418: if ( tt->base == ILIST )
1419: e->e1 = tt;
1420:
1421: if (e->e1->base == ILIST) {
1422: extern Pbase mptr_type;
1423: Pexpr mptr_assign(Pexpr, Pexpr);
1424: // memptr constant
1425: // f({1,2,f}) ==> memptr t; f((t={1,2,f},t))
1426: Pname temp = make_tmp('A',mptr_type,tbl);
1427: e->e1 = mptr_assign(temp,e->e1);
1428: e->e1 = a = new expr(G_CM,e->e1,temp);
1429: a->tp = temp->tp;
1430: }
1431:
1432: }
1433: else {
1434: if (k != ELLIPSIS) {
1435: error("unexpected %dA for%n",argno,fn);
1436: return any_type;
1437: }
1438: goto rlab;
1439: }
1440: }
1441: else { /* default argument? */
1442: a = nn->n_initializer;
1443: if (a == 0) {
1444: error("A %d ofT%tX for%n",argno,nn->tp,fn);
1445: return any_type;
1446: }
1447: if (a->base == ILIST) {
1448: extern Pbase mptr_type;
1449: Pexpr mptr_assign(Pexpr, Pexpr);
1450: // memptr constant
1451: // f({1,2,f}) ==> memptr t; f((t={1,2,f},t))
1452: Pname temp = make_tmp('A',mptr_type,tbl);
1453: a = mptr_assign(temp,a);
1454: a = new expr(G_CM,a,temp);
1455: a->tp = temp->tp;
1456: }
1457: a->permanent = 2; // ought not be necessary, but it is
1458: e = new expr(ELIST,a,0);
1459: if (etail)
1460: etail->e2 = e;
1461: else
1462: e2 = e;
1463: etail = e;
1464: }
1465: }
1466:
1467: rlab:
1468: //error('d',"rlab fct_name %n %t",fct_name,fct_name?fct_name->tp:0);
1469: for (; e; e = e->e2) { // unchecked arguments
1470: Pexpr a = e->e1;
1471: Pname cn;
1472:
1473: if (a->base==NAME && a->tp->base==FCT) {
1474: // function name that escaped the type system:
1475: // update use count
1476: a->lval(ADDROF);
1477: }
1478: else if (cn = a->tp->is_cl_obj()) {
1479: Pclass cl = Pclass(cn->tp);
1480: if (cl->has_ctor() || cl->memtbl->look("__as",0)/*cl->has_oper(ASSIGN)*/)
1481: error("O ofC%t withK or = copied",cl);
1482: }
1483: else if (a->tp->is_ref())
1484: e->e1 = a->contents();
1485: }
1486:
1487: if (f->f_result) { // f(args) => (f(&temp,args),temp)
1488: Pname tn = make_tmp('R',f->returns,tbl);
1489: e2 = new expr(ELIST,tn->address(),e2);
1490: //error('d',"result %n",fn);
1491: Pexpr ee = new expr(0,0,0);
1492: *ee = *this;
1493: base = G_CM; // (f(&temp,args),temp)
1494: e1 = ee;
1495: e2 = tn;
1496: tp = tn->tp;
1497: }
1498:
1499: return t;
1500: }
1501:
1502: Pexpr ref_init(Pptr p, Pexpr init, Ptable tbl)
1503: /*
1504: initialize the "p" with the "init"
1505: remember to call ptr_init to ensure that pointers to second bases
1506: are handled correctly.
1507: */
1508: {
1509: register Ptype it = init->tp;
1510: Pptr px = p;
1511: while (px->base == TYPE) px = Pptr(Pbase(px)->b_name->tp);
1512: Ptype p1 = px->typ;
1513: Pname c1 = p1->is_cl_obj();
1514: //error('d',"ref_init: p %t, p1 %t, px %t, init->tp %t",p,p1,px,it);
1515:
1516: if (init->base == ILIST) error("IrL as RIr");
1517:
1518: if (init->base==NAME
1519: && Pname(init)->n_scope==ARG
1520: && init->tp->base==FLOAT)
1521: error('w',"initializing a float& with floatA is non-portable");
1522:
1523: rloop:
1524: switch (it->base) {
1525: case TYPE:
1526: it = Pbase(it)->b_name->tp; goto rloop;
1527: default:
1528: { Ptype tt = it->addrof();
1529: px->base = PTR; // allow &x for y& when y : public x
1530: // but not &char for int&
1531: int x = px->check(tt,COERCE);
1532:
1533: if (x == 0) { //CCC type is fine check for constness:
1534: if (init->tp->tconst()
1535: && vec_const==0
1536: && fct_const==0) {
1537: // not ``it''
1538: if (init->base == ELIST) init = init->e1;
1539: if (px->typ->tconst() == 0) error("R to constO");
1540: px->base = RPTR;
1541: // if we have a const lvalue we can still pass its address
1542: extern ignore_const;
1543: ignore_const++;
1544: if (init->lval(0)) {
1545: init->lval(ADDROF); // force output
1546: ignore_const--;
1547: //error('d',"in1 %t",init->tp);
1548: return ptr_init(px,init->address(),tbl);//return init->address();
1549: }
1550: ignore_const--;
1551: goto xxx;
1552: }
1553: px->base = RPTR;
1554: if (init->lval(0)) { // can pass the address // no temporary needed
1555: init->lval(ADDROF); // force output
1556: //error('d',"px %t init %t init %t",px,init->tp,init->tp);
1557: return ptr_init(px,init->address(),tbl);
1558: }
1559: goto xxx;
1560: }
1561:
1562: px->base = RPTR;
1563: }
1564: }
1565:
1566: //error('d',"c1 %n",c1);
1567: if (c1) { // assigning to a const X & is fine
1568: ref_cast++;
1569: Pexpr x = try_to_coerce(p,init,"reference initialization",tbl);
1570: ref_cast--;
1571: if (x) {
1572: init = x;
1573: goto xxx;
1574: }
1575: while (p1->base==TYPE) p1 = Pbase(p1)->b_name->tp;
1576: int bc = Pbase(p1)->b_const;
1577: Pbase(p1)->b_const = 0;
1578: refd = 1; /* disable itor */
1579: Pexpr a = class_init(0,p1,init,tbl);
1580: Pbase(p1)->b_const = bc;
1581: refd = 0;
1582: if (a==init && init->tp!=any_type) goto xxx;
1583: //error('d',"ri a %d %k",a->base,a->base);
1584: switch (a->base) {
1585: case G_CALL:
1586: // case CM:
1587: // case G_CM:
1588: init = a;
1589: goto xxx;
1590: }
1591: a = a->address();
1592: //error('d',"ri2 a %d %k",a->base,a->base);
1593: a = ptr_init(px,a,tbl);
1594: //error('d',"ri3 a %d %k",a->base,a->base);
1595: return a;
1596: // return ptr_init(px,a->address(),tbl);//a->address();
1597: }
1598:
1599: //error('d',"p1 %t it %t",p1,it);
1600: if (p1->check(it,0)) {
1601:
1602: if (p1->check(it,ASSIGN) == 0) {
1603: // if (p1->is_ptr()) // check for base* = derived*
1604: // goto xxx;
1605:
1606: // things like ``double& rr = 1;'' temporary needed
1607: // warn in case of ``slightly wrong lvalue'', e.g.
1608: // int i; double& r = i;
1609: if (init->lval(0) && p1->tconst()==0) error('w',"conversion of lvalue needed: temporary used toI reference");
1610: goto def;
1611: }
1612:
1613: Pexpr x = try_to_coerce(p1,init,"reference",tbl); // x==init
1614: if (x==0) x = try_to_coerce(px,init,"reference",tbl); // x&=init
1615: if (x) {
1616: init = x;
1617: goto def;
1618: }
1619:
1620: error("badIrT:%t (%tX)",it,p);
1621: if (init->base != NAME) init->tp = any_type;
1622: return init;
1623: }
1624:
1625: xxx: /*
1626: here comes the test of a ``fundamental theorem'':
1627: a structure valued expression is
1628: (1) an lvalue of type T (possibly const)
1629: or (2) the result of a function (a _result if X(X&) is defined)
1630: or (3) a * or [] or ? or , expression
1631: */
1632: //error('d',"xxx %k %d %t",init->base,init->base,init->tp);
1633:
1634: switch (init->base) {
1635: case NAME:
1636: case DEREF:
1637: case REF:
1638: case DOT: // init => &init
1639: if (it->tconst() && vec_const==0 && fct_const==0) goto def;
1640: init->lval(ADDROF);
1641: if (vec_const) return init;
1642: if (fct_const && p1->is_ptr()) goto def; // fptr& = fct
1643: // no break
1644: case CM:
1645: case G_CM: // & (f(&temp), temp)
1646: return ptr_init(px,init->address(),tbl);//init->address();
1647: default:
1648: def:
1649: {
1650: //error('d',"def: init->tp %t p1 %t",init->tp,p1);
1651: if (tbl == gtbl) error("Ir for staticR not an lvalue");
1652: Pname n = make_tmp('I',p1,tbl);
1653: Pexpr a;
1654: Pname ic = init->tp->is_cl_obj();
1655:
1656: if (p1->tconst()==0
1657: && (init->tp->tconst() && vec_const==0 && fct_const==0)
1658: && p1->check(it,ASSIGN)==0)
1659: error('w',"constIr: temporary used toI reference");
1660:
1661: switch (p1->base) {
1662: case INT:
1663: case CHAR:
1664: case SHORT:
1665: switch (it->base) {
1666: case LONG:
1667: case FLOAT:
1668: case DOUBLE:
1669: case LDOUBLE:
1670: error('w',"%t assigned to %t inRIr",it,p1);
1671: }
1672: }
1673:
1674: if (ic!=c1 && Pclass(ic->tp) != Pclass(c1->tp)) {
1675: // derived class1 => must cast: ``it Ix; (Ix=init,(p)&Ix);''
1676: n->tp = init->tp;
1677: a = ptr_init(px,n->address(),tbl);//n->address();
1678: PERM(p);
1679: a = new texpr(CAST,p,a);
1680: a->tp = p;
1681: }
1682: else
1683: a = n->address();
1684:
1685: refd = 1;
1686: Pexpr as = init_tmp(n,init,tbl);
1687: refd = 0;
1688: a = new expr(G_CM,as,a);
1689: a->tp = a->e2->tp;
1690: return a;
1691: }
1692: }
1693: }
1694:
1695: Pexpr class_init(Pexpr nn, Ptype tt, Pexpr init, Ptable tbl)
1696: /*
1697: initialize "nn" of type "tt" with "init"
1698: if nn==0 make a temporary,
1699: nn may not be a name
1700: */
1701: {
1702: if (init == dummy) return 0;
1703: //error('d',"class_init %t with %t init %k refd %d",tt,init->tp,init->base,refd);
1704: Pname c1 = tt->is_cl_obj();
1705:
1706: if (init == 0) {
1707: error("emptyIr");
1708: return dummy;
1709: }
1710:
1711: if (c1) {
1712: Pclass cl = Pclass(c1->tp);
1713: Pname c2 = init->tp->is_cl_obj();
1714:
1715: if (c1!=c2 || (refd==0 && cl->has_itor())) {
1716: /* really ought to make a temp if refd,
1717: but ref_init can do that
1718: */
1719: int i = can_coerce(tt,init->tp);
1720: //error('d',"i %d nn %n",i,nn);
1721: switch (i) {
1722: default:
1723: error("%d ways of making a%n from a%t",i,c1,init->tp);
1724: init->tp = any_type;
1725: return init;
1726: case 0:
1727: if (c2 && Pclass(c2->tp)->has_base(cl)) {
1728: init = init->address();
1729: Pexpr x = cast_cptr(cl,init,tbl,0);
1730:
1731: if (x == init) {
1732: Ptype pt = tt->addrof();
1733: PERM(pt);
1734: x = new cast(pt,init);
1735: }
1736:
1737: return x->contents();
1738: }
1739: error("cannot make a%n from a%t",c1,init->tp);
1740: init->tp = any_type;
1741: return init;
1742: case 1:
1743: //error('d',"ncoerce %n %k %d",Ncoerce,init->base,init->base);
1744: if (Ncoerce == 0) {
1745: Pexpr a = new expr(ELIST,init,0);
1746: a = new texpr(VALUE,tt,a);
1747: a->e2 = nn;
1748: // return a->typ(tbl);
1749: a = a->typ(tbl);
1750: //error('d',"ci a %k %d %t",a->base,a->base,a->tp);
1751: return a;
1752: }
1753:
1754: switch (init->base) {
1755: case CM:
1756: case G_CM: //ddd
1757: case NAME: /* init.coerce() */
1758: /* *ref */ case DEREF:
1759: { Pref r = new ref(DOT,init,Ncoerce);
1760: Pexpr rr = r->typ(tbl);
1761: init = new expr(G_CALL,rr,0);
1762: init->fct_name = Ncoerce;
1763: break;
1764: }
1765: default: // (temp=init,temp.coerce())
1766: { Pname tmp = make_tmp('U',init->tp,tbl);
1767: int x = refd;
1768: refd = 0; // ??
1769: Pexpr ass = init_tmp(tmp,init,tbl);
1770: refd = x;
1771: Pref r = new ref(DOT,tmp,Ncoerce);
1772: Pexpr rr = r->typ(tbl);
1773: Pexpr c = new expr(G_CALL,rr,0);
1774: c->fct_name = Ncoerce;
1775: c = c->typ(tbl);
1776: init = new expr(CM,ass,c);
1777: init->tp = c->tp;
1778: if (refd) { // &f() => (t=f(), &t)
1779: Pname tmp2 = make_tmp('L',c->tp,tbl);
1780: ass = init_tmp(tmp2,init,tbl);
1781: init = new expr(G_CM,ass,tmp2);
1782: }
1783: }
1784: }
1785: //error('d',"nn %n",nn);
1786: if (nn) {
1787: Pexpr a = new expr(ELIST,init,0);
1788: a = new texpr(VALUE,tt,a);
1789: a->e2 = nn;
1790: return a->typ(tbl);
1791: }
1792: }
1793: //error('d',"c1 %n c2 %n",c1,c2);
1794: return init->typ(tbl);
1795: }
1796: return init;
1797: }
1798: //error('d',"ci check tt %t init->tp %t",tt,init->tp);
1799: if (tt->check(init->tp,ASSIGN) && refd==0) {
1800: error("badIrT:%t (%tX)",init->tp,tt);
1801: init->tp = any_type;
1802: }
1803:
1804: return init;
1805: }
1806:
1807: extern int bound; // fudge for bound pointers to functions
1808:
1809: Pexpr expr::docast(Ptable tbl)
1810: {
1811: // check cast against value, INCOMPLETE
1812:
1813: //error('d',"docast %d %t %k",this,tp2,e1->base);
1814: if (e1 == dummy) {
1815: error("E missing for cast");
1816: tp = any_type;
1817: return this;
1818: }
1819:
1820: int pmf = 0;
1821: int ptom_cast = 0;
1822: Pexpr ee = e1;
1823:
1824: //error('d',"ee %k %d",ee->base,ee->base);
1825: switch (ee->base) {
1826: case ADDROF:
1827: ee = ee->e2;
1828: switch (ee->base) {
1829: case NAME: goto nm;
1830: case REF: goto rf;
1831: }
1832: break;
1833:
1834: case NAME:
1835: nm:
1836: if (Pname(ee)->n_qualifier) pmf = 1;
1837: break;
1838:
1839: case REF:
1840: rf:
1841: if (ee->e1->base == THIS) bound = 1;
1842: break;
1843: }
1844:
1845: e1 = e1->typ(tbl);
1846:
1847: int b = bound; // distinguish between explicit and implicit THIS
1848: bound = 0;
1849: pmf = pmf && e1->base==CAST;
1850:
1851: Ptype etp = e1->tp;
1852: Ptype tt = tp2;
1853: Ptype t = tt;
1854: tt->dcl(tbl);
1855:
1856: while (etp->base == TYPE) etp = Pbase(etp)->b_name->tp;
1857: while (tt->base == TYPE) tt = Pbase(tt)->b_name->tp;
1858:
1859: //error('d',"e1 %k etp %t tt %t",e1->base,etp,tt);
1860:
1861: switch (etp->base) {
1862: case PTR:
1863: case RPTR:
1864: if (Pptr(etp)->typ->base == OVERLOAD) goto over;
1865:
1866: if (warning_opt && i2==0 && Pptr(etp)->typ->tconst()) {
1867: switch (tt->base) {
1868: case FCT:
1869: break;
1870: case PTR:
1871: case RPTR:
1872: if (Pptr(tt)->typ->tconst()) break;
1873: default:
1874: // casting away const
1875: // should be an error
1876: // but ANSI says OK so I chicken out
1877: // to be able to compile strtok(), etc.
1878: error('w',"const cast away:%t->%t",e1->tp,tp2);
1879: }
1880: }
1881: else
1882: i2 = 0; // to allow cfront to escape its own checking
1883: break;
1884: case COBJ:
1885: { ref_cast = 1;
1886: Pexpr x = try_to_coerce(tt,e1,"cast",tbl);
1887: ref_cast = 0;
1888: //error('d',"x %k %t tt %d %t",x?x->base:0,x?x->tp:0,tt,tt);
1889: if (x) {
1890: if (x!=e1 && x->base==DEREF && tt->is_ref()) x = x->e1;
1891: if (tt==x->tp || tt->check(x->tp,0)==0 || const_problem)
1892: return x;
1893: else
1894: return new cast(tt,x);
1895: }
1896: // else if (e1->base==DEREF && tt->is_ref()) return e1;
1897: break;
1898: }
1899: case VOID:
1900: if (tt->base == VOID) {
1901: tp = t;
1902: return this;
1903: }
1904: error("cast of void value");
1905: // no break;
1906: case ANY:
1907: any:
1908: tp = any_type;
1909: return this;
1910: case FCT:
1911: if (tt->base == PTR && Pptr(tt)->typ->base != FCT)
1912: error('w',"P toF cast toP to nonF");
1913: break;
1914: case OVERLOAD:
1915: over:
1916: error("cast of overloaded");
1917: goto any;
1918: }
1919:
1920: //error('d',"tt %t",tt);
1921: switch (tt->base) {
1922: case PTR:
1923: if (Pptr(tt)->typ->base==FCT && Pptr(tt)->memof) {
1924: if (etp->base!=PTR
1925: || Pptr(etp)->typ->base!=FCT
1926: || Pptr(etp)->memof==0)
1927: error("cast toP toM %t",tt);
1928: else { // adjust delta in MI case
1929: // for the moment just suppress the cast
1930: // all pmfs are the same to cc
1931: /*
1932: Pclass c1 = Pptr(tt)->memof;
1933: Pclass c2 = Pptr(etp)->memof;
1934: */
1935: ptom_cast = 1;
1936: tp2 = void_type;
1937: }
1938: }
1939:
1940: switch (etp->base) {
1941: case COBJ:
1942: error("cannot castCO toP");
1943: break;
1944: case FCT:
1945: e1 = new expr(G_ADDROF,0,e1);
1946: bound = b;
1947: e1 = e1->typ(tbl);
1948: bound = 0;
1949: if (e1->base == CAST)
1950: pmf = 1;
1951: else
1952: break;
1953: // no break;
1954:
1955: case PTR:
1956: { Pname cn = Pptr(tt)->typ->is_cl_obj();
1957: if (cn) {
1958: Pexpr x = cast_cptr(Pclass(cn->tp),e1,tbl,1);
1959:
1960: if (x == e1) {
1961: PERM(tt);
1962: e1 = new cast(tt,e1);
1963: e1->i2 = i2;
1964: }
1965: else
1966: e1 = x;
1967: }
1968: if (pmf) {
1969: zaqq:
1970: switch (tt->base) {
1971: case TYPE:
1972: tt = Pbase(tt)->b_name->tp; goto zaqq;
1973: case PTR:
1974: if (Pptr(tt)->memof) break;
1975: default:
1976: error("%t cast to%t (%t is not aP toM)",e1->tp,tp2,tp2);
1977: }
1978: }
1979: }
1980: }
1981: break;
1982:
1983: case RPTR: // (x&)e: pretend e is an x
1984: { Ptype er = etp;
1985: Ptype cr = tt;
1986: do {
1987: if (er = er->is_ptr_or_ref()) er = Pptr(er)->typ;
1988: if (cr = cr->is_ptr_or_ref()) cr = Pptr(cr)->typ;
1989: } while (er && cr);
1990: int pp = er!=0; // if `e' is a suitable pointer cast it:
1991: // (x&)e => (x*)e, otherwise
1992: // (x&)e => *(x*)&e
1993: //error('d',"rptr tt %t e1->base %k e1->tp %t",tt,e1->base,e1->tp);
1994: // if (Pptr(tt)->typ->tsizeof()>etp->tsizeof()) goto zse;
1995: // we need to be able to ``raise the type'' from base to derived
1996: // if (etp->is_cl_obj() && Pptr(tt)->typ->is_cl_obj()==0) goto zse;
1997:
1998: if (e1->base==G_CM
1999: || e1->base==CALL
2000: || e1->base==G_CALL
2001: || e1->lval(0))
2002: ;
2003: else if (e1->tp->tconst()) {
2004: // casting away const
2005: // should be an error
2006: // but ANSI says OK so I chicken out
2007: // to be able to compile strtok(), etc.
2008: if (warning_opt && Pptr(tt)->typ->tconst()==0)
2009: error('w',"const cast away:%t->%t",e1->tp,tp2);
2010:
2011: }
2012: else
2013: error("cannot cast%t to%t",etp,t);
2014: //error('d',"e1 %k %t %d",e1->base,e1->tp,pp);
2015: if (pp == 0) e1 = e1->address(); // *(x*)&e
2016: tp = t;
2017:
2018: // do proper pointer manipulation for multiple inheritance
2019: Pname cn = Pptr(tt)->typ->is_cl_obj();
2020: if (cn) {
2021: Pexpr x = cast_cptr(Pclass(cn->tp),e1,tbl,1);
2022:
2023: if (x == e1) {
2024: PERM(tt);
2025: e1 = new cast(tt,e1);
2026: e1->i2 = i2;
2027: }
2028: else
2029: e1 = x;
2030: }
2031:
2032: return pp ? this : contents();
2033: // zse:
2034: // error("cannot cast%t to%t",etp,t);
2035: // tp2 = tt = any_type;
2036: // break;
2037: }
2038: case COBJ:
2039: base = VALUE; // (x)e => x(e): construct an x from e
2040: e1 = new expr(ELIST,e1,0);
2041: return typ(tbl);
2042:
2043: case CHAR:
2044: case INT:
2045: case SHORT:
2046: case LONG:
2047: case FLOAT:
2048: case DOUBLE:
2049: case LDOUBLE:
2050: switch (etp->base) {
2051: case FCT:
2052: e1 = new expr(ADDROF,0,e1);
2053: e1 = e1->typ(tbl);
2054: break;
2055: case COBJ:
2056: error("cannot castCO to%k",tt->base);
2057: break;
2058: }
2059: break;
2060: }
2061:
2062: tp = t;
2063:
2064: if (e1->base==ILIST && ptom_cast==0) { // pointer to member constant
2065: Pexpr ee = e1->e1; // ELIST
2066: int i;
2067: switch (ee->e2->base) {
2068: case IVAL:
2069: i = int(ee->e2->i1);
2070: break;
2071: case ZERO:
2072: i = 0;
2073: }
2074:
2075: if (i<0)
2076: e1 = e1->e2; // just the function
2077: else
2078: e1 = ee->e2; // just the index
2079: return this;
2080: }
2081:
2082: if (etp->base==PTR && Pptr(etp)->memof && Pptr(etp)->typ->base==FCT) {
2083: Pclass cl = Pptr(etp)->memof;
2084:
2085: if (Pptr(tt)->memof==0 && b == 0 ) {
2086: Pexpr y = new mdot("f",e1);
2087: y->i1 = 9;
2088: y = new cast(tt,y);
2089: if (cl->virt_count && b==0) {
2090: // ERROR: no check for side effects
2091: Pexpr z = new mdot("i",e1);
2092: Pexpr x = new mdot("i",e1);
2093: x->i1 = 9;
2094: x = new cast(tt,x);
2095: z->i1 = 9;
2096: Pexpr q = new expr (QUEST,x,y);
2097: q->cond = new expr(LE,zero,z);
2098: q->tp = tt;
2099: delete this;
2100: return q;
2101: }
2102: delete this;
2103: return y;
2104: }
2105: }
2106:
2107: return this;
2108: }
2109:
2110: Pexpr expr::dovalue(Ptable tbl)
2111: {
2112: Ptype tt = tp2;
2113: Pclass cl;
2114: Pname cn;
2115:
2116: //error('d',"value %d %t e1 %d e2 %d",tt,tt,e1,e2);
2117:
2118: tt->dcl(tbl);
2119: vv:
2120: switch (tt->base) {
2121: case TYPE:
2122: tt = Pbase(tt)->b_name->tp;
2123: goto vv;
2124:
2125: case EOBJ:
2126: default:
2127: if (e1 == 0) {
2128: error("value missing in conversion to%t",tt);
2129: return dummy;
2130: }
2131: base = CAST;
2132: e1 = e1->e1; // strip ELIST
2133: return typ(tbl);
2134:
2135: case CLASS:
2136: cl = Pclass(tt);
2137: tp2 = Pptr(cl->this_type)->typ;
2138: break;
2139:
2140: case COBJ:
2141: cn = Pbase(tt)->b_name;
2142: cl = Pclass(cn->tp);
2143: }
2144:
2145: //error('d',"e1 %k e1->e2 %k",e1->base,e1?e1->e2->base:0);
2146: if (e1 && e1->e2==0) { // single argument
2147: if (e1->e1->base==ELIST) e1->e1 = e1->e1->e1; // spurious elist
2148: e1->e1 = e1->e1->typ(tbl);
2149: if (tt->base==COBJ) {
2150: Pexpr x = try_to_coerce(tt,e1->e1,"type conversion",tbl);
2151: if (x) return x;
2152: }
2153:
2154: Pname acn = e1->e1->tp->is_cl_obj();
2155: //error('d',"acn %n %d",acn,cl->has_itor());
2156: if (acn && cl->has_itor()==0) {
2157: Pclass acl = Pclass(acn->tp);
2158: int hb = acl->has_base(cl);
2159:
2160: if (acl==cl || hb) {
2161: vcllist->clear();
2162: vcllist=0;
2163: if (1<is_unique_base(acl,cl->string,0)) error("ambiguous assignment to base %t",cl);
2164: Pexpr ee = e1->e1;
2165: if (ee->base == ELIST) ee = ee->e1; // ???
2166: if (hb) { // ee => *(tp2*)&ee
2167: // remember = may be overloaded
2168: //error('d',"hb %k %t %d",ee->base,ee->tp,ee->lval(0));
2169: if (ee->lval(0)==0) {
2170: Pname tmp = make_tmp('T',ee->tp,tbl);
2171: ee = init_tmp(tmp,ee,tbl);
2172: ee = new expr(G_CM,ee,tmp->address());
2173: }
2174: else
2175: ee = ee->address();
2176: ee = new texpr(CAST,new ptr(PTR,tp2),ee); //new cast(new ptr(PTR,tp2),ee);
2177: ee = ee->contents();
2178: ee->typ(tbl);
2179: }
2180:
2181: if (e2) { // x(x_obj) => e2=x_obj
2182: base = ASSIGN;
2183: e1 = e2;
2184: e2 = ee;
2185: tp = tp2;
2186: return this;
2187: }
2188: return ee; // strip ELIST: x(x_obj) => x_obj
2189: }
2190: }
2191: }
2192:
2193:
2194: /* x(a) => obj.ctor(a); where e1==obj */
2195: Pname ctor = cl->has_ctor();
2196: if (ctor == 0) {
2197: error("cannot make a%t",cl);
2198: return dummy;
2199: }
2200:
2201: //error('d',"e2 %k",e2?e2->base:0);
2202: if (e2 == 0) { // x(a) => x temp; (temp.x(a),temp)
2203: Pname n = make_tmp('V',tp2,tbl);
2204: n->assign();
2205: if (tbl == gtbl) n->dcl_print(0); // a hack
2206: Pexpr c = call_ctor(tbl,n,ctor,e1,DOT);
2207: c = new expr(G_CM,c,n);
2208: c->tp = n->tp;
2209: //error('d',"tp1 %t",c->tp);
2210: return c;
2211: }
2212: else {
2213: Pexpr c = call_ctor(tbl,e2,ctor,e1,DOT);
2214: c = new expr(DEREF,c,0); // deref value returned by constructor
2215: c->tp = c->e1->tp;
2216: //error('d',"tp2 %t",c->tp);
2217: return c;
2218: }
2219: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.