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