|
|
1.1 root 1: /*ident "@(#)ctrans:src/expr.c 1.12" */
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: expr.c:
11:
12: type check expressions
13:
14: ************************************************************************/
15:
16: #include "cfront.h"
17: #include "size.h"
18:
19: int const_save;
20: int const_ptr;
21: extern Ptype Pfct_type;
22:
23: Pexpr expr::address()
24: {
25: // error('d',"address %k %d %s",base,base,base==NAME||base==ANAME?string:"?");
26: // error('d',"address e1 %d %k e2 %d %k", e1, e1?e1->base:0, e2, e2?e2->base:0);
27: switch (base) {
28: case DEREF:
29: if (e2 == 0) return e1; // &*e => e
30: break;
31: case QUEST: // &(a?b:c) => a?&b:&c
32: e1 = e1->address();
33: // no break;
34: case G_CM:
35: if ( e1 && e1->base == G_CALL &&
36: e2 && e2->base == G_ADDROF)
37: return this;
38: case CM:
39: e2 = e2->address(); // &(e1,e2) => (e1,&e2)
40: tp = e2->tp; //LLL
41: return this;
42: case INCR:
43: case DECR: // &(++a) => (++a,&a)
44: if (e1) break;
45: nin++;
46: if (e2->not_simple()) error('s',"& of%k",base);
47: nin--;
48: e1 = new expr(base,0,e2);
49: e2 = e2->address();
50: base = G_CM;
51: tp = e2->tp;
52: return this;
53: case ASSIGN: // &(a=b) => ((a=b),&a)
54: case ASPLUS:
55: case ASMINUS:
56: case ASMUL:
57: case ASDIV:
58: case ASMOD:
59: case ASAND:
60: case ASOR:
61: case ASER:
62: case ASLS:
63: case ASRS:
64: nin++;
65: if (e1->not_simple()) error('s',"& of%k",base);
66: nin--;
67: Pexpr a = new expr(base,e1,e2);
68: a->tp = a->e1->tp;
69: base = G_CM;
70: e1 = a;
71: e2 = a->e1->address();
72: tp = e2->tp;
73: return this;
74:
75: case NAME:
76: if (Pname(this)->n_stclass == REGISTER) error("& register%n",Pname(this));
77: Pname(this)->take_addr();
78: break;
79: case CALL:
80: case CAST:
81: case NEW:
82: case GNEW:
83: if (tp && tp->is_ptr_or_ref()) { // hack?
84: return this;
85: }
86: break;
87: }
88:
89: register Pexpr ee = new expr(G_ADDROF,0,this);
90: if (tp) { // tp==0 ???
91: ee->tp = tp->addrof();
92:
93: switch (tp->base) {
94: case PTR:
95: Pptr(ee->tp)->memof = Pptr(tp)->memof;
96: break;
97: case FCT:
98: if (Pfct(tp)->f_static==0)
99: Pptr(ee->tp)->memof = Pfct(tp)->memof;
100: break;
101: case OVERLOAD:
102: if (Pfct(Pgen(tp)->fct_list->f->tp)->f_static==0)
103: Pptr(ee->tp)->memof = Pfct(Pgen(tp)->fct_list->f->tp)->memof;
104: }
105: }
106:
107: return ee;
108: }
109:
110: Pexpr expr::contents()
111: {
112: //error('d',"deref %k %d %t",base,base,tp);
113: // if (base==ADDROF || base==G_ADDROF) return e2; // *&
114: switch (base) {
115: case ADDROF:
116: case G_ADDROF:
117: return e2; // *&
118: case ELIST:
119: //error('d',"contents of elist");
120: e1 = e1->contents();
121: tp = e1->tp;
122: return this;
123: };
124:
125: register Pexpr ee = new expr(DEREF,this,0);
126: if (tp) { // tp==0 ???
127: Ptype tt = tp;
128: while (tt->base == TYPE)
129: tt = tt->bname_type();
130: ee->tp = Pptr(tt)->typ;
131: Pname cn = ee->tp->is_cl_obj();
132: if (cn) {
133: // look for first use of class
134: Pclass cl = Pclass(cn->tp);
135: if (cl->c_body==1) cl->dcl_print(0);
136: }
137: }
138: return ee;
139: }
140:
141: static Pexpr
142: make_postfix( Pexpr op, Pname fn=0 ) {
143: /* apply the postfix form of increment/decrement operator
144: * if (fn) special call from check_postscipt to handle
145: * the two operator instances declared at different scopes
146: * i.e., member and non-member, therefore stored as FCTs.
147: */
148: Pfct f;
149: Plist fl;
150: Pname n = fn?fn:0;
151: Pexpr e = op->e1->base==NAME?op->e1:op->e1->mem;
152: if (n) goto mk_postfix; // sorry(!!!)
153:
154: for (fl=Pgen(e->tp)->fct_list;fl; fl=fl->l) {
155: n = fl->f;
156: f = Pfct(n->tp);
157: if ((f->nargs==1 && f->f_this) ||
158: (f->nargs==2 && f->f_this==0)) {
159:
160: mk_postfix: // rewrite the call expression
161: if (op->e1->base == NAME) {
162: op->e1 = n;
163: op->e2->e2 = new expr(ELIST,zero,0);
164: } else {
165: op->e1->mem = n;
166: op->e2 = new expr(ELIST,zero,0);
167: }
168:
169: op->fct_name = n;
170: n->dcl_print(0);
171: return op;
172: }
173: }
174: error('w',"no postfix instance of%n, although overloaded",Pname(e));
175: return op; // as it were
176: }
177:
178: static Pexpr
179: check_postfix( Pexpr op ) {
180: /* special case: member and non-member operator++/-- instances
181: * each stored as FCT, and so try_to_overload returns prefix instance
182: * need to make an explicit check if postfix instance exists
183: */
184: int is_glob = op->e1->base==NAME ? 1: 0;
185: Pname fn = is_glob ? Pname(op->e1) : Pname(op->e1->mem);
186:
187: // error('d',"check_postfix: fn: %n is_glob: %d",fn,is_glob);
188:
189: if (is_glob == 0) { // found operator++/--() as member
190: Pname n = gtbl->look(fn->string,0);
191: Ptype arg_tp = op->e1->e1->tp;
192:
193: if (n==0) return op;
194: if (n->tp->base == FCT) { // one global instance
195: Pfct ff = Pfct(n->tp);
196:
197: // error('d',"check_postfix: global n:%n arg: %t act: %t",n,ff->argtype->tp,arg_tp);
198: extern int exact1(Pname,Ptype); // place in cfront.h
199:
200: if (ff->nargs != 2) return op;
201: if (exact1(ff->argtype, arg_tp)==0) return op;
202: return make_postfix(op,n);
203: }
204: if (n->tp->base == OVERLOAD) { // multiple global instances
205: for (Plist fl=Pgen(n->tp)->fct_list; fl; fl=fl->l) {
206: Pname nn = fl->f;
207: Pfct ff = Pfct(nn->tp);
208: if (ff->nargs != 2) continue;
209: if (exact1(ff->argtype, arg_tp)==0) continue;
210: return make_postfix(op,nn);
211: }
212: return op;
213: }
214: }
215: else { // examine class table for postfix member
216: Pfct f = Pfct(fn->tp);
217: Pptr p = f->argtype->tp->is_ptr_or_ref();
218: Ptype t = p?p->typ:f->argtype->tp;
219: Pname cn = t->is_cl_obj();
220: if (cn == 0) error('i',"check_postfix: %n(%n %t),CTX",fn,f->argtype,t);
221:
222: Pname nn = Pclass(cn->tp)->memtbl->look(fn->string,0);
223: // error('d',"check_postfix: found: %n %t", nn, nn->tp);
224: if (nn) return make_postfix(op,nn);
225: return op;
226: }
227: }
228:
229: int bound;
230: int chars_in_largest; // no of characters in largest int
231: static Pclass mpglob;
232:
233: Pexpr expr::typ(Ptable tbl)
234: /*
235: find the type of "this" and place it in tp;
236: return the typechecked version of the expression:
237: "tbl" provides the scope for the names in "this"
238: */
239: {
240: //if (this == 0) error('i',"0->expr::typ");
241: Pname n;
242: Ptype t = 0;
243: Ptype t1, t2;
244: TOK b = base;
245: TOK r1, r2;
246: #define nppromote(b) t=np_promote(b,r1,r2,t1,t2,1)
247: #define npcheck(b) (void)np_promote(b,r1,r2,t1,t2,0)
248: if (tbl->base != TABLE) error('i',"expr::typ(%d)",tbl->base);
249:
250: DB( if(Tdebug>=1) {
251: error('d',"%d->expr::typ(%d) %k %t",this,tbl,b,tp);
252: display_expr(this);
253: });
254: // error('d',"%k->typ %n tp: %t", b,b==NAME?this:0,tp);
255: // error('d'," e1 %d %k e1 %d %k",e1,e1?e1->base:0,e2,e2?e2->base:0);
256:
257: if (tp) {
258: switch (b) {
259: case NAME:
260: //?? Pname(this)->use();
261: break;
262: case MDOT:
263: mem = mem->typ(tbl);
264: } ;
265: // if (b == NAME) Pname(this)->use();
266: return this;
267: }
268:
269: extern Pname Ntmp;
270:
271: switch (b) { // is it a basic type
272: case MDOT:
273: error('i',"mdot %s",string2);
274: case DUMMY:
275: error("emptyE");
276: tp = any_type;
277: return this;
278:
279: case ZERO:
280: tp = zero_type;
281: return this;
282:
283: case IVAL:
284: tp = int_type;
285: return this;
286:
287: //case FVAL:
288: // tp = float_type;
289: // return this;
290:
291: case ICON:
292: /* is it long?
293: explicit long?
294: decimal larger than largest signed int
295: octal or hexadecimal larger than largest unsigned int
296: */
297: { int ll = strlen(string);
298: switch (string[ll-1]) {
299: case 'l':
300: case 'L':
301: switch (string[ll-2]) {
302: case 'u':
303: case 'U':
304: string[ll-2] = 0;
305: tp = ulong_type;
306: goto cast_n_save;
307: }
308: lng:
309: tp = long_type;
310: goto save;
311: case 'u':
312: case 'U': // 1u => unsigned(1)
313: switch (string[ll-2]) {
314: case 'l':
315: case 'L':
316: string[ll-2] = 0;
317: ulng:
318: tp = ulong_type;
319: goto cast_n_save;
320: default:
321: string[ll-1] = 0;
322: uint:
323: tp = uint_type;
324: goto cast_n_save;
325: }
326: }
327:
328: // no suffix - see if we can figure it out
329: if (string[0] == '0') { // assume 8 bits in byte
330: register index = 1;
331: switch (string[1]) {
332: case 'x':
333: case 'X':
334: while(string[++index]=='0') ;
335: ll -= index;
336: int HSZ = SZ_INT+SZ_INT;
337: if(ll < HSZ) goto nrm;
338: if(ll == HSZ)
339: if(string[2]>='8') goto uint;
340: else goto nrm;
341: if(SZ_INT==SZ_LONG) break;
342: HSZ = SZ_LONG+SZ_LONG;
343: if(ll < HSZ) goto lng;
344: if(ll == HSZ)
345: if(string[2]>='8') goto ulng;
346: else goto lng;
347: break;
348: default: // OCTAL
349: register IBITS = BI_IN_BYTE*SZ_INT;
350: while(string[index]=='0') index++;
351: register char x = string[index];
352: int lbt = x=='1' ? 1 :
353: ( x=='2' || x=='3' ? 2 : 3 );
354: int nbits = (ll-index-1)*3 + lbt;
355: if(nbits < IBITS) goto nrm;
356: if(nbits == IBITS) goto uint;
357: if(nbits < BI_IN_BYTE*SZ_LONG) goto lng;
358: }
359: goto ulng;
360: }
361: else { // DECIMAL
362: if (ll<chars_in_largest) {
363: nrm:
364: tp = int_type;
365: goto save;
366: }
367: if (ll>chars_in_largest) {
368: if(SZ_INT==SZ_LONG || ll>2*chars_in_largest)
369: goto ulng;
370: goto lng;
371: }
372: // ll == chars_in_largest
373: char* p = string;
374: char* q = LARGEST_INT;
375: do if (*p>*q) {
376: if(SZ_INT==SZ_LONG) goto ulng;
377: goto lng;
378: } while (*p++==*q++ && *p);
379: }
380:
381: goto nrm;
382: }
383: case CCON:
384: tp = c_strlen(string)<5 ? char_type : int_type; // stored as 'a'
385: goto save;
386:
387: case FCON:
388: { int ll = strlen(string);
389: int last = string[ll-1];
390: tp = double_type;
391: if (last=='F' || last=='f') {
392: tp = float_type;
393: if (!ansi_opt) {
394: string[ll-1] = 0;
395: goto cast_n_save;
396: }
397: }
398: else if (last=='L' || last=='l') {
399: if (ansi_opt == 0) string[ll-1] = 0;
400: tp = ldouble_type;
401: }
402: goto save;
403: }
404: case STRING: // type of "as\tdf" is char[6]
405: // c_strlen counts the terminating '\0'
406: { Pvec v = new vec(char_type,0);
407: v->size = c_strlen(string);
408: tp = v;
409: }
410: save:
411: if (const_save) { // "as\tdf" needs 7 chars for storage
412: char* p = new char[strlen(string)+1];
413: strcpy(p,string);
414: string = p;
415: }
416:
417: return this;
418:
419: cast_n_save:
420: if (const_save) { // "as\tdf" needs 7 chars for storage
421: char* p = new char[strlen(string)+1];
422: strcpy(p,string);
423: string = p;
424: }
425:
426: return new cast(tp,this);
427:
428: case THIS:
429: delete this;
430: if (cc->c_this) {
431: cc->c_this->use();
432: return cc->c_this;
433: }
434: error("``this'' used in nonC context");
435: n = new name("this");
436: n->tp = any_type;
437: return tbl->insert(n,0);
438:
439: case NAME:
440: {
441: Pname q = Pname(this)->n_qualifier; // suppress virtual iff x::
442: Pexpr ee = find_name(Pname(this),cc->cot,tbl,0,cc->nof);
443: if (q && (ee->base==REF || ee->base==DOT))
444: ee->n_initializer = Pexpr(q);
445: //error('d',"ee %k %t %n",ee->base,ee->tp,ee->base==NAME?ee:ee->base==REF?ee->mem:0);
446: // if (ee->tp->base == RPTR) return ee->contents();
447: if (ee->tp->is_ref()) return ee->contents();
448:
449: if (ee->base==NAME && Pname(ee)->n_xref) {
450: // fudge to handle X(X&) args
451: ee = new expr(DEREF,ee,0);
452: ee->tp = ee->e1->tp; // !!
453: }
454:
455: return ee;
456: }
457:
458: case ADDROF:
459: case G_ADDROF: // handle lookup for &s::i
460: mpglob = 0;
461: if (e2->base == NAME) e2 = find_name(Pname(e2),cc->cot,tbl,ADDROF,cc->nof);
462: if (e2->base==NAME && Pname(e2)->n_xref) {
463: // fudge to handle X(X&) args
464: e2 = new expr(DEREF,e2,0);
465: e2->tp = e2->e1->tp; // !!
466: }
467: if (e2->base==DOT) { // &f().x = > &(tmp=f(),&tmp)->x
468: switch (e2->e1->base) {
469: case CALL:
470: case G_CALL:
471: case VALUE:
472: error("& non-lvalue");
473: }
474: }
475: break;
476:
477: case SIZEOF:
478: if (tp2) {
479: tp2->dcl(tbl);
480: switch (tp2->base) {
481: case VOID:
482: error("sizeof(void)");
483: break;
484: case CLASS:
485: {
486: Pclass cl = Pclass(tp2);
487: if (cl->c_body==1
488: && (cl->defined&(DEFINED|SIMPLIFIED)) == 0)
489: error('s',"class defined within sizeof");
490: }
491: }
492:
493: if (e1 && e1!=dummy) {
494: e1 = e1->typ(tbl);
495: DEL(e1);
496: e1 = dummy;
497: }
498: Pptr r = tp2->is_ref();
499: if (r) tp2 = r->typ; // sizeof(T&)==sizeof(T)
500: }
501: else if (e1 == dummy) {
502: error("sizeof emptyE");
503: tp = any_type;
504: return this;
505: }
506: else {
507: e1 = e1->typ(tbl);
508: tp2 = e1->tp;
509: if(tp2->base == VEC) tp2->permanent = 1;
510: if (e1->base==ILIST) // PtoM
511: e1 = dummy;
512: else if (tp2 == char_type) // sizeof ('a')
513: e1 = dummy;
514: }
515: (void) tp2->tsizeof();
516: tp = size_t_type;
517: return this;
518:
519: case CAST:
520: // return docast(tbl);
521:
522: { Pexpr ee = docast(tbl);
523: return ee->tp->is_ref() ? ee->contents() : ee;
524: }
525:
526:
527: case VALUE:
528: if ( tp2->base == COBJ || tp2->base == EOBJ) {
529: Pname tp2_name = tp2->bname();
530: char *s = tp2_name->string;
531: //Pname tn = gtbl->look( s, 0 );
532: //??? non type name apparently takes precedence
533: // Don't use global ftn if it hides local
534: // class ctor. (Note: More info is needed
535: // to detect all cases.)
536: Pname tn = tbl->look( s, 0 );
537: //error( 'd', "tn: %n %t lex_levels: %d %d", tn, tn?tn->tp:0, tn?tn->lex_level:0, Pbase(tp2)->b_name->lex_level );
538: if ( tn && tn->n_qualifier == 0
539: && tn->lex_level == tp2_name->lex_level
540: && (tn->tp->base==FCT || tn->tp->base==OVERLOAD))
541: {
542: Pexpr et = new expr( CALL, tn, e1 );
543: *this = *et;
544: b = CALL;
545: break;
546: }
547: }
548: return dovalue(tbl);
549:
550: case NEW:
551: case GNEW:
552: return donew(tbl);
553:
554: case DELETE: // delete e1 OR delete[e2] e1
555: case GDELETE:
556: { int i;
557: if (e1->base == ADDROF) error('w',"delete &E");
558: e1 = e1->typ(tbl);
559: i = e1->tp->num_ptr(DELETE);
560: if (i != 'P') error("nonP deleted");
561: if (e2) {
562: e2 = e2->typ(tbl);
563: e2->tp->integral(DELETE);
564: }
565: tp = void_type;
566: return this;
567: }
568:
569: case ILIST: /* an ILIST is pointer to an ELIST */
570: e1 = e1->typ(tbl);
571: tp = any_type;
572: return this;
573:
574: case ELIST:
575: { Pexpr e;
576: Pexpr ex;
577:
578: if (e1 == dummy && e2==0) {
579: error("emptyIrL");
580: tp = any_type;
581: return this;
582: }
583:
584: for (e=this; e; e=ex) {
585: Pexpr ee = e->e1;
586: //error('d',"e %d %d ee %d %d",e,e?e->base:0,ee,ee?ee->base:0);
587: if (e->base != ELIST) error('i',"elist%k",e->base);
588: if (ex = e->e2) { /* look ahead for end of list */
589: if (ee == dummy) error("EX in EL");
590: if (ex->e1 == dummy && ex->e2 == 0) {
591: /* { ... , } */
592: DEL(ex);
593: e->e2 = ex = 0;
594: }
595: }
596: e->e1 = ee->typ(tbl);
597: t = e->e1->tp;
598: if (t->base == FCT) { // yuk!
599: ee = new expr(G_ADDROF,0,e->e1);
600: e->e1 = ee->typ(tbl);
601: t = e->e1->tp;
602: }
603: }
604: tp = t;
605: return this;
606: }
607:
608: case DOT:
609: case REF:
610: { if (e2) { // *. or ->*
611: if (b == REF) b = base = REFMUL;
612: break;
613: }
614:
615: Pbase b;
616:
617: e1 = e1->typ(tbl);
618: t = e1->tp;
619:
620: // check that . (->) is applied to class object (pointer)
621: if (base == REF) {
622: xxx:
623: switch (t->base) {
624: case TYPE:
625: t = t->bname_type();
626: goto xxx;
627: case COBJ:
628: {
629: Pname n = t->classtype()->has_oper(REF);
630: if (n) {
631: n->n_used += 2;
632: e1 = new call(new ref(DOT,e1,n),0);
633: return typ(tbl);
634: }
635: // no break;
636: }
637: default:
638: error("nonP ->%n",mem);
639: t = any_type;
640: // no break;
641: case ANY:
642: goto qqq;
643: case PTR:
644: case VEC:
645: b = Pbase(Pptr(t)->typ);
646: }
647: }
648: else { // base == DOT
649: qqq:
650: switch (t->base) {
651: case TYPE:
652: t = t->bname_type();
653: goto qqq;
654:
655: default: error("nonO .%n",mem); t = any_type;
656: case ANY:
657: case COBJ: break;
658: }
659: //error('d',"dot %k",e1->base);
660: switch (e1->base) {
661: case QUEST:
662: case ASSIGN:
663: case INCR:
664: case DECR:
665: case ASPLUS:
666: case ASMINUS:
667: case ASMUL:
668: case ASDIV:
669: case ASMOD:
670: case ASAND:
671: case ASOR:
672: case ASER:
673: case ASLS:
674: case ASRS:
675: case CM:
676: case G_CM:
677: base = REF;
678: e1 = e1->address();
679: break;
680: case CALL:
681: case G_CALL:
682: //error('d'," f(). %n mem->tp %t",e1->fct_name,mem->tp);
683: #ifdef FDOTRIGHT
684: // this rewrite is only necessary on machines with broken C compilers
685: // there seems to be a lot of those
686: // and for inlines (a,b).c
687: if (e1->fct_name && Pfct(e1->fct_name->tp)->f_inline)
688: #endif
689: { // f(). => (tmp=f(),&tmp)->
690: Pname tmp = make_tmp('Q',e1->tp,tbl);
691: //error('d',"fdot2 %k",e1->base);
692: e1 = init_tmp(tmp,e1,tbl);
693: Pexpr aa = tmp->address();
694: e1 = new expr(G_CM,e1,aa);
695: e1->tp = aa->tp;
696: base = REF;
697: break;
698: }
699: }
700: b = Pbase(t);
701: }
702:
703: xxxx:
704: switch (b->base) {
705: case TYPE:
706: b = (Pbase)b->bname_type();
707: goto xxxx;
708: default:
709: error("(%t) before %k%n (%n not aM)",e1->tp,base,mem,mem);
710: case ANY:
711: tp = any_type;
712: return this;
713: case COBJ:
714: {
715: Pclass cl = b->classtype();
716: if (cl->c_body == 1) cl->dcl_print(0);
717: break;
718: }
719: }
720:
721: /*
722: x.m is not a const even if x is a const object, this case is handled
723: by lval() rejecting it
724: */
725:
726: if (mem->tp) {
727: tp = mem->tp;
728: for (Pexpr ee = mem; ee->base==REF; ee = ee->e1) {
729: if (ee->e1 == cc->c_this) { // this-> => p->
730: ee->e1 = e1;
731: ee->base = base;
732: return mem->tp->is_ref() ? mem->contents() : mem;
733: }
734: }
735:
736: // return tp->base==RPTR ? contents() : this;
737: return tp->is_ref() ? contents() : this;
738: }
739:
740:
741: Pname q = Pname(mem)->n_qualifier;
742: Pexpr e = find_name(Pname(mem),b->classtype(),0,base,cc->nof);
743: if (q && (e->base==REF || e->base==DOT))
744: Pname(e)->n_initializer = Pexpr(q);
745: //error('d',"e %k %t %n",e->base,e->tp,e->base==NAME?e:e->base==REF?e->mem:0);
746:
747: for (Pexpr ee = e; ee->base==REF; ee = ee->e1) {
748: if (ee->e1 == cc->c_this) { // this-> => p->
749: ee->e1 = e1;
750: ee->base = base;
751: break;
752: }
753: }
754:
755: if (e->base == NAME) {
756: switch (e->tp->base) {
757: case FCT:
758: case OVERLOAD:
759: mem = e;
760: tp = e->tp;
761: e = this;
762: }
763: }
764:
765: // function or static member
766: return e->tp->is_ref() ? e->contents() : e;
767: }
768:
769: //?? case G_CALL:
770: case CALL: /* handle undefined function names */
771: //error('d',"call %k %t %k",e1->base,e1->tp,e2?e2->base:0);
772: if (e1->base==NAME && e1->tp==0) {
773: Pname q = Pname(e1)->n_qualifier;
774: e1 = find_name(Pname(e1),cc->cot,tbl,CALL,cc->nof);
775: //error('d',"e1 %k %t %n",e1->base,e1->tp,e1->base==NAME?e1:e1->base==REF?e1->mem:0);
776: if (q && (e1->base==REF ||e1->base==DOT)) // suppress virtual call
777: e1->n_initializer = Pexpr(q);
778: }
779:
780: if (e1->base==NAME && Pname(e1)->n_xref) {
781: // fudge to handle X(X&) args
782: e1 = new expr(DEREF,e1,0);
783: e1->tp = e1->e1->tp; // !!
784: }
785:
786: switch (e1->base) {
787: case DOT:
788: /*
789: #ifdef FDOTRIGHT
790: {
791: //error('d',"fdot1 %k",e1->e1->base);
792: switch (e1->e1->base) {
793: case CALL:
794: case G_CALL: // f().g() => (tmp=f(),tmp.g())
795: { Pexpr ee = e1->e1;
796: Pexpr ex = ee->typ(tbl);
797: Pname tmp = make_tmp('Q',ex->tp,tbl);
798: ex = init_tmp(tmp,ex,tbl);
799:
800: Pexpr ee2 = new expr(base,e1,e2);
801: e1->base = DOT;
802: e1->e1 = tmp;
803:
804: base = G_CM;
805: e1 = ex;
806: e2 = ee2;
807:
808: return typ(tbl);
809: }
810: }
811: break;
812: }
813: #endif
814: */
815: case REF: // becomes ob.x::~x(0) or
816: if (e2==0 // becomes p->x::~x(0)
817: && Pref(e1)->mem
818: && Pref(e1)->mem->base==NAME
819: && Pname(Pref(e1)->mem)->n_oper==DTOR) {
820: e1 = e1->typ(tbl);
821: Pexpr ee = call_dtor(e1->e1,Pref(e1)->mem,0,e1->base,one);
822: ee->tp = void_type;
823: return ee;
824: }
825: }
826: break;
827:
828: case QUEST:
829: cond = cond->typ(tbl);
830: case ANDAND:
831: case OROR:
832: Ntmp = 0;
833: }
834:
835: if (e1) {
836: e1 = e1->typ(tbl);
837: if (e1->tp->is_ref()) e1 = e1->contents();
838: t1 = e1->tp;
839: // if (t1->is_cl_obj()) t1->tsizeof();
840: }
841: else
842: t1 = 0;
843:
844: if (e2) {
845: e2 = e2->typ(tbl);
846: if (e2->tp->is_ref()) e2 = e2->contents();
847: t2 = e2->tp;
848: // if (t2->is_cl_obj()) t2->tsizeof();
849: }
850: else
851: t2 = 0;
852:
853: // error('d',"b %k t1 %t t2 %t",b,t1,t2);
854: switch (b) { // filter out non-overloadable operators
855: default:
856: {
857: Pexpr x = try_to_overload(tbl);
858: if (x) {
859: if (b==INCR || b==DECR) {
860: Pexpr fe = x->e1->base==NAME?x->e1:x->e1->mem;
861: if (t2==0 && t1) { // postfix
862: if (fe->tp->base==OVERLOAD)
863: x = make_postfix(x);
864: else x = check_postfix(x);
865: }
866: }
867: return x;
868: }
869: // if (x) return x;
870: // error('d',"e2: %t t2: %t", e2->tp, t2);
871: if (t2 && t1==0 && t2!=e2->tp) t2 = e2->tp;
872: }
873: case DOT:
874: case G_CM:
875: case G_ADDROF:
876: case G_CALL:
877: case QUEST:
878: break;
879: }
880:
881: switch (b) {
882: case QUEST:
883: case ANDAND:
884: case OROR:
885: if (Ntmp) error('s',"temporary ofC%n with destructor needed in%kE",Ntmp,b);
886: }
887:
888: t = (t1==0) ? t2 : (t2==0) ? t1 : 0;
889: // error('d', "expr::typ t %t", t );
890: // error('d',"b2 %d %k",b,b);
891: switch (b) { /* are the operands of legal types */
892: case REFMUL:
893: base = REF;
894: // no break;
895: case DOT:
896: { // a .* p => &a MEMPTR p => appropriate indirection
897: // to be considered: what happens if a .* expression
898: // is used except in a call/=?
899: Pexpr a = e1->typ(tbl);
900: Ptype at = a->tp;
901: if (base == DOT) {
902: a = a->address();
903: at = at->addrof(); // beware of n_xref
904: }
905:
906: while (at->base == TYPE)
907: at = at->bname_type();
908: Pname cn = Pptr(at)->typ->is_cl_obj();
909: Pclass mm = cn ? Pclass(cn->tp) : 0;
910:
911: Pexpr p = e2->typ(tbl);
912: Ptype pt = p->tp;
913: Pname pcn = pt->is_cl_obj();
914:
915: //error('d',"mm %t pt %t",mm,pt);
916: if (pcn) {
917: Pclass cl = Pclass(pcn->tp);
918: Pname found = 0;
919: for (Pname on=cl->conv; on; on=on->n_list) {
920: Pfct f = Pfct(on->tp);
921: Pptr frt = Pptr(f->returns);
922: while (frt->base == TYPE)
923: frt = (Pptr)frt->bname_type();
924: if (frt->base!=PTR || Pptr(frt)->memof==0) break;
925: if (Pptr(frt)->memof==mm || mm->has_base(Pptr(frt)->memof)) {
926: if (found)
927: error("two possible conversions forP toM: %n and %n",found,on);
928: else
929: found = on;
930: }
931: }
932: //error('d',"found %n",found);
933: if (found) {
934: p = new ref(DOT,p,found);
935: p = new call(p,0);
936: p = p->typ(tbl);
937: pt = p->tp;
938: }
939:
940: }
941: while (pt->base == TYPE)
942: pt = pt->bname_type();
943: if (pt->base!=PTR || Pptr(pt)->memof==0) {
944: error("P toMX in .*E: %t",pt);
945: tp = any_type;
946: base = DUMMY;
947: return this;
948: }
949: Pclass pm = Pptr(pt)->memof;
950:
951: // while (at->base == TYPE) at = Pbase(at)->b_name->tp;
952: // Pname cn = Pptr(at)->typ->is_cl_obj();
953: // Pclass mm = cn ? Pclass(cn->tp) : 0;
954: //error('d',"mm %t %t %d %d",mm,pm,pm->baseof(mm),mm->has_base(pm));
955:
956: // if (mm!=pm && pm->baseof(mm)==0 && mm->has_base(pm)==0) {
957: if (mm != pm) {
958: if (mm->has_base(pm) == 0) {
959: error("badOT in .*E: %t (%s*X)",a->tp,pm->string);
960: tp = any_type;
961: //return this;
962: }
963: a = new texpr(CAST,pm->this_type,a);
964: e1 = a = a->typ(tbl);
965: }
966:
967: Ptype tpx = Pptr(pt)->typ;
968: while (tpx->base == TYPE)
969: tpx = tpx->bname_type();
970:
971: if (tpx->base == FCT) { // a.*p => (&a MEMPTR p)
972: base = MEMPTR;
973: tp2 = mm; // keep the class for simpl.c
974: e1 = a;
975: e2 = p;
976: }
977: else { // a .* p => *(typeof(p))((char*)&a + (int)p-1)
978: a = new cast(Pchar_type,a);
979: p = new cast(int_type,p);
980: p = new expr(MINUS,p,one);
981: p->tp = int_type;
982: Pexpr pl = new expr(PLUS,a,p);
983: pl->tp = Pchar_type;
984: base = DEREF;
985: pt = new ptr(PTR,tpx); // need a T* not a T C::*
986: Pptr(pt)->rdo = Pptr(tpx)->rdo;
987: mpglob = pm;
988: // PERM(pt);
989: e1 = new cast(pt,pl);
990: e2 = 0;
991: }
992: tp = tpx;
993: return tp->is_ref() ? contents() : this;
994: }
995:
996: case G_CALL:
997: case CALL:
998: tp = call_fct(tbl); /* two calls of use() for e1's names */
999: if (tp->is_ref()) return contents();
1000: return this;
1001:
1002: case DEREF:
1003: if (e1 == dummy) error("O missing before []\n");
1004: if (e2 == dummy) error("subscriptE missing");
1005:
1006: if (t) { /* *t */
1007: while (t->base == TYPE)
1008: t = t->bname_type();
1009: // t->vec_type();
1010: if (t->base==PTR && Pptr(t)->memof) error("P toM dereferenced");
1011: tp = t->deref();
1012: }
1013: else { // e1[e2] that is *(e1+e2)
1014: //error('d',"deref %t[%t]",t1,t2);
1015: if (t1->vec_type()) { // e1[e2]
1016: switch (t2->base) {
1017: case CHAR:
1018: case SHORT:
1019: case INT:
1020: case LONG:
1021: case EOBJ:
1022: break;
1023: default:
1024: { Pname cn = t2->is_cl_obj();
1025: if (cn) // conversion to integral?
1026: e2 = check_cond(e2,DEREF,tbl);
1027: else
1028: t2->integral(DEREF);
1029: }
1030: }
1031: while (t1->base == TYPE)
1032: t1 = t1->bname_type();
1033: if (t1->base==PTR && Pptr(t1)->memof) error("P toM dereferenced");
1034: tp = t1->deref();
1035: (void) tp->tsizeof();
1036: }
1037: else if (t2->vec_type()) { // really e2[e1]
1038: t1->integral(DEREF);
1039: while (t2->base == TYPE)
1040: t2 = t2->bname_type();
1041: if (t2->base==PTR && Pptr(t2)->memof) error("P toM dereferenced");
1042: tp = t2->deref();
1043: (void) tp->tsizeof();
1044: }
1045: else {
1046: error("[] applied to nonPT:%t[%t]",t1,t2);
1047: tp = any_type;
1048: }
1049: }
1050:
1051: if (tp->is_ref()) return contents();
1052:
1053: return this;
1054:
1055: case G_ADDROF:
1056: case ADDROF:
1057: //error('d',"addrof(%d) %k %d",base,e2->base,e2->base);
1058: switch (e2->base) { // potential lvalues
1059: case G_CM:
1060: if (base==ADDROF && e2->e2->base==NAME) {
1061: // check for cfront generated result variable
1062: char* s = e2->e2->string;
1063: if (s[0]=='_' && s[1] && s[1]=='_') {
1064: if (s[2] && (s[2]=='R' || s[2]=='V')) {
1065: error("address of non-lvalue");
1066: break;
1067: }
1068: }
1069: }
1070: case CM: // &(a,b) => (a,&b)
1071: {
1072: Pexpr ee = e2;
1073: ee->tp = 0;
1074: ee->e2 = new expr(base,0,ee->e2);
1075: delete this;
1076: return ee->typ(tbl);
1077: }
1078: case QUEST: // & (a?b:c) => (a?&b:&c)
1079: {
1080: Pexpr ee = e2;
1081: ee->tp = 0;
1082: ee->e1 = new expr(base,0,ee->e1);
1083: ee->e2 = new expr(base,0,ee->e2);
1084: delete this;
1085: return ee->typ(tbl);
1086: }
1087: case INCR:
1088: case DECR:
1089: if (e2->e1) break;
1090: case ASSIGN:
1091: case ASPLUS:
1092: case ASMINUS:
1093: case ASMUL:
1094: case ASDIV:
1095: case ASMOD:
1096: case ASAND:
1097: case ASOR:
1098: case ASER:
1099: case ASLS:
1100: case ASRS:
1101: return e2->address();
1102: }
1103:
1104: if (e2->lval(ADDROF) == 0) {
1105: if (error_count) { // error_count == 0 possible
1106: // in case of & const
1107: tp = any_type;
1108: return this;
1109: }
1110: }
1111:
1112: tp = t->addrof();
1113:
1114: if( base==ADDROF && mpglob)
1115: Pptr(tp)->memof = mpglob;
1116:
1117: if (e2->tp->base == VEC) {
1118: if(e2->base != NAME) {
1119: base = CAST;
1120: tp2 = tp;
1121: e1 = e2;
1122: e2 = 0;
1123: return this;
1124: }
1125: }
1126:
1127: // tp = t->addrof();
1128:
1129: if (t->base==FCT)
1130: Pptr(tp)->memof = Pfct(t)->memof;
1131:
1132: // if (t->tconst() && vec_const==0 && fct_const==0) Pptr(tp)->rdo = 1;
1133: // ??? & (const T) is NOT T*const but const T*
1134:
1135: switch (e2->base) {
1136: case NAME:
1137: mname: // check for &s::i
1138: { Pname n2 = Pname(e2);
1139: Pname cn = (n2->n_table && n2->n_table!=gtbl) ? n2->n_table->t_name : 0;
1140: // error('d',"n2 %k cn %n t %t",n2->base,cn,t);
1141: if (cn == 0) break;
1142: // Pptr(tp)->memof = Pclass(cn->tp);
1143:
1144: if (t->base==FCT && Pfct(t)->f_this==0) {
1145: Pptr(tp)->memof = 0;
1146: break;
1147: }
1148:
1149: switch (t->base) {
1150: case OVERLOAD:
1151: return e2;
1152: case FCT:
1153: // error('d', "cn->tp: %d, %k", cn->tp, cn->tp->base);
1154: Pptr(tp)->memof = Pclass(cn->tp); //SSS
1155:
1156: if (Pfct(t)->f_virtual) {
1157: // { 0,vtbl index,0 }
1158: e1 = new ival(Pfct(t)->f_virtual);
1159: e1 = new expr(ELIST,zero,e1);
1160: e2 = zero;
1161: base = ILIST;
1162: // tp = int_type;
1163: return this;
1164: } // use the pointer
1165:
1166: // { 0,-1,(int(*)())ptr }
1167: e1 = new ival(-1);
1168: e1 = new expr(ELIST,zero,e1);
1169: // e2 is the name
1170: e2 = new cast(Pfct_type,e2);
1171: base = ILIST;
1172: // tp = int_type;
1173: return this;
1174:
1175: // return e2;
1176:
1177: default:
1178: if (n2->n_stclass != STATIC) { // offset + 1
1179: //error('d',"n2 %n %d",n2,n2->n_offset);
1180: //error('d',"q %n cn %n",n2->n_qualifier,cn);
1181: e1 = new ival(n2->n_offset+1);
1182: Pptr(tp)->memof = Pclass(cn->tp);
1183: //error('d',"cl %d %s i %d",Pclass(cn->tp),Pclass(cn->tp)?Pclass(cn->tp)->string:"0",n2->n_offset);
1184: }
1185: else
1186: return this;
1187: }
1188: //error('d',"int_type");
1189: e1->tp = int_type;
1190: e2 = 0;
1191: tp2 = tp;
1192: base = CAST;
1193: return this;
1194: }
1195: case DOT:
1196: case REF:
1197: {
1198: Pname m = Pname(e2->mem);
1199: // error( 'd', "e2->mem->base: %k", e2->mem->base );
1200: // Pname m = (e2->mem->base == MDOT) ? Pname(e2->mem->mem) : Pname(e2->mem);
1201: while ( m->base == MDOT ) m = Pname(Pexpr(m)->mem);
1202:
1203: Pfct f = Pfct(m->tp);
1204:
1205: if (f->base == FCT || f->base == OVERLOAD) { // &p->f
1206: Pexpr q = Pname(e2)->n_initializer; // &p->x::f
1207:
1208: if (q && bound==0 && e2->e1==cc->c_this) {
1209: // FUDGE: &this->x::f => &x::f
1210: DEL(e2);
1211: e2 = m;
1212: goto mname;
1213: }
1214:
1215: bound = 1;
1216: if(!f->f_static) {
1217: error(strict_opt?0:'w',
1218: "address of boundF (try using ``%s::*'' forPT and ``&%s::%s'' for address) (anachronism)",
1219: m->n_table->t_name->string,
1220: m->n_table->t_name->string,
1221: m->string
1222: );
1223: }
1224:
1225: if (q || f->f_virtual==0) {
1226: // & x.f => & f
1227: DEL(e2);
1228: e2 = m;
1229: }
1230: }
1231: break;
1232:
1233: }
1234: case MEMPTR:
1235: // &(p->*q)
1236: error("& .* E");
1237: }
1238:
1239: return this;
1240:
1241: case UMINUS:
1242: t->numeric(UMINUS);
1243: tp = t;
1244: return this;
1245:
1246: case UPLUS:
1247: t->num_ptr(UPLUS);
1248: tp = t;
1249: if (ansi_opt==0) {
1250: base = PLUS;
1251: e1 = zero;
1252: }
1253: return this;
1254:
1255: case NOT:
1256: e2 = check_cond(e2,NOT,tbl);
1257: tp = int_type;
1258: return this;
1259:
1260: case COMPL:
1261: t->integral(COMPL);
1262: tp = t;
1263: return this;
1264:
1265: case INCR:
1266: case DECR:
1267: {
1268: // error('d',"incr-decr: e1: %k e2: %k", e1?e1->base:0, e2?e2->base:0);
1269: Pexpr e = e1?e1:e2; // e1!=0 ==> e++ or e--
1270: // e1==0 ==> ++e or --e
1271:
1272: e->lval(b);
1273:
1274: switch(e->base) {
1275: case QUEST:
1276: e->tp=0;
1277: e->e1 = e1 ? new expr(base,e->e1,0) : new expr(base,0,e->e1);
1278: e->e2 = e1 ? new expr(base,e->e2,0) : new expr(base,0,e->e2);
1279: delete this;
1280: return e->typ(tbl);
1281: case CM:
1282: case G_CM:
1283: e->tp=0;
1284: e->e2 = e1 ? new expr(base,e->e2,0) : new expr(base,0,e->e2);
1285: delete this;
1286: return e->typ(tbl);
1287: case INCR:
1288: case DECR:
1289: if(e->e1)
1290: break;
1291: nin++;
1292: if(e->e2->not_simple())
1293: error('s',"overly complex %k of %k",b,e->base);
1294: nin--;
1295: e = new expr(G_CM,e,e->e2->typ(tbl));
1296: if (e1) e1=e; else e2=e;
1297: // e1?e1:e2 = e;
1298: return typ(tbl);
1299: case ASSIGN:
1300: case ASPLUS:
1301: case ASMINUS:
1302: case ASMUL:
1303: case ASDIV:
1304: case ASMOD:
1305: case ASAND:
1306: case ASOR:
1307: case ASER:
1308: case ASLS:
1309: case ASRS:
1310: nin++;
1311: if(e->e1->not_simple())
1312: error('s',"overly complex %k of %k",b,e->base);
1313: nin--;
1314: e = new expr(G_CM,e,e->e1->typ(tbl));
1315: if (e1) e1=e; else e2=e;
1316: // e1?e1:e2 = e;
1317: return typ(tbl);
1318: }
1319: }
1320:
1321: r1 = t->num_ptr(b);
1322: if (r1='P' && t->check(Pvoid_type,0)==0) error("%k of void*",b);
1323: tp = t;
1324: return this;
1325:
1326: }
1327:
1328: if (e1==dummy || e2==dummy || e1==0 || e2==0) error("operand missing for%k",b);
1329: switch (b) {
1330: case MUL:
1331: case DIV:
1332: r1 = t1->numeric(b);
1333: r2 = t2->numeric(b);
1334: nppromote(b);
1335: break;
1336:
1337: case PLUS:
1338: r2 = t2->num_ptr(PLUS);
1339: r1 = t1->num_ptr(PLUS);
1340: nppromote(PLUS);
1341: goto void_check;
1342:
1343: case MINUS:
1344: r2 = t2->num_ptr(MINUS);
1345: r1 = t1->num_ptr(MINUS);
1346: if (r2=='P' && r1!='P' && r1!='A') error("nonP - P");
1347: nppromote(MINUS);
1348: void_check:
1349: if ((r1='P' && t1->check(Pvoid_type,0)==0)
1350: || (r2='P' && t2->check(Pvoid_type,0)==0))
1351: error("%k of void*",b);
1352: tp = t;
1353: break;
1354:
1355: case LS:
1356: case RS:
1357: case AND:
1358: case OR:
1359: case ER:
1360: switch (e1->base) {
1361: case LT:
1362: case LE:
1363: case GT:
1364: case GE:
1365: case EQ:
1366: case NE:
1367: error('w',"%kE as operand for%k",e1->base,b);
1368: }
1369: switch (e2->base) {
1370: case LT:
1371: case LE:
1372: case GT:
1373: case GE:
1374: case EQ:
1375: case NE:
1376: error('w',"%kE as operand for%k",e2->base,b);
1377: }
1378: case MOD:
1379: r1 = t1->integral(b);
1380: r2 = t2->integral(b);
1381: nppromote(b);
1382: break;
1383:
1384: case LT:
1385: case LE:
1386: case GT:
1387: case GE:
1388: case EQ:
1389: case NE:
1390: r1 = t1->num_ptr(b);
1391: r2 = t2->num_ptr(b);
1392: if (r1=='P' && r2=='I') { // allow things like:
1393: // if (p==2-2)
1394: // YUCK!
1395: Neval = 0;
1396: long i = e2->eval();
1397: if (Neval==0 && i==0) {
1398: DEL(e2);
1399: e2 = zero;
1400: r2 = 'Z';
1401: }
1402: }
1403: else if (r2=='P' && r1=='I') {
1404: Neval = 0;
1405: long i = e1->eval();
1406: if (Neval==0 && i==0) {
1407: DEL(e1);
1408: e1 = zero;
1409: r1 = 'Z';
1410: }
1411: }
1412:
1413: if (b!=EQ && b!=NE) {
1414: if (r1=='P' && r2=='Z') error("P%k 0",b);
1415: if (r2=='P' && r1=='Z') error("P%k 0",b);
1416: }
1417:
1418: // make sure functions are properly converted to pointers to
1419: // functions and make sure overloaded functions are rejected
1420: Pexpr ptof(Pfct ef, Pexpr e, Ptable tbl);
1421: if (r1 == FCT) e1 = ptof(0,e1,tbl);
1422: if (r2 == FCT) e2 = ptof(0,e2,tbl);
1423:
1424: npcheck(b);
1425:
1426: if (r1=='P') { // need cast for pointers to virtual and second bases
1427: Pptr p1 = t1->is_ptr();
1428: Pptr p2 = t2->is_ptr();
1429: Pname cn = p1?p1->typ->is_cl_obj():0;
1430: Pname cn2 = p2?p2->typ->is_cl_obj():0;
1431:
1432: if (cn && cn2) {
1433: Pclass cl = Pclass(cn->tp);
1434: Pclass cl2 = Pclass(cn2->tp);
1435:
1436: if (cl->has_base(cl2)) {
1437: e1 = cast_cptr(cl2,e1,tbl,0);
1438: e1 = new cast(p2,e1);
1439: }
1440: else if (cl2->has_base(cl)) {
1441: e2 = cast_cptr(cl,e2,tbl,0);
1442: e2 = new cast(p1,e2);
1443: }
1444: }
1445: }
1446:
1447: if (r1=='P' && t1->memptr()) {
1448: mpmp:
1449: if (r2=='Z') {
1450: e2 = zero;
1451: e1 = new mdot("i",e1);
1452: e1->i1 = 9;
1453: }
1454: else if (r2=='P' && t2->memptr()) {
1455: // ERROR: no check for sideeffects
1456: Pexpr i1 = new mdot("i",e1);
1457: Pexpr i2;
1458: i1->i1 = 9;
1459:
1460: i2 = e2;
1461: while ( i2->base == CAST )
1462: i2 = i2->e1;
1463: if ( i2->base == ILIST )
1464: e2 = i2;
1465:
1466: if (e2->base==ILIST)
1467: i2 = e2->e1->e2;
1468: else {
1469: i2 = new mdot("i",e2);
1470: i2->i1 = 9;
1471: }
1472:
1473: Pexpr f1 = new mdot("f",e1);
1474: Pexpr f2;
1475: f1->i1 = 9;
1476: if (e2->base == ILIST)
1477: // f2 = new cast(Pfct_type,e2->e2);
1478: f2 = e2->e2;
1479: else {
1480: f2 = new mdot("f",e2);
1481: f2->i1 = 9;
1482: }
1483:
1484: Pexpr ei = new expr(base,i1,i2);
1485: Pexpr fi = new expr(base,f1,f2);
1486:
1487: base = ANDAND;
1488: e1 = ei;
1489: e2 = fi;
1490: } else if (r2=='P') {
1491: error('s',"%t %k %t",t1,base,t2);
1492: }
1493: }
1494: else if (r2=='P' && t2->memptr()) {
1495: Pexpr ee = e1; // swap
1496: e1 = e2;
1497: e2 = ee;
1498: int rr = r1;
1499: r1 = r2;
1500: r2 = rr;
1501: Ptype tt = t1;
1502: t1 = t2;
1503: t2 = tt;
1504: goto mpmp;
1505: }
1506: t = int_type;
1507: break;
1508:
1509: case ANDAND:
1510: case OROR:
1511: e1 = check_cond(e1,b,tbl);
1512: e2 = check_cond(e2,b,tbl);
1513: t = int_type;
1514: break;
1515:
1516: case QUEST:
1517: {
1518: Pname c1, c2;
1519: cond = check_cond(cond,b,tbl);
1520: //error('d',"cond %k %t",cond->base,cond->tp);
1521: //error('d',"t1 %t t2 %t",t1,t2);
1522:
1523: // still doesn't do complete checking for possible conversions...
1524:
1525: bit MPTR = 0; // local hack
1526:
1527: extern int suppress_error; // global hack
1528: suppress_error++;
1529: r1 = t1->num_ptr(b);
1530: r2 = t2->num_ptr(b);
1531: suppress_error--;
1532: if (r1=='P' && r2=='P' && t1->memptr() && t2->memptr()) {
1533:
1534: ++MPTR; // prevent later sorry
1535:
1536: // watch for casts
1537: Pexpr tt = e1;
1538: while ( tt->base == CAST ) tt = tt->e1;
1539: if ( tt->base == ILIST ) e1 = tt;
1540:
1541: tt = e2;
1542: while ( tt->base == CAST ) tt = tt->e1;
1543: if ( tt->base == ILIST ) e2 = tt;
1544:
1545: // cannot have sides return (expr?{}:{})
1546: // reuse same temp for both sides ?:
1547: Pname temp = make_tmp( 'A', mptr_type, tbl );
1548:
1549: e1 = mptr_assign( temp, e1 );
1550: e1 = new expr( G_CM, e1, temp );
1551: e1->tp = temp->tp;
1552:
1553: e2 = mptr_assign( temp, e2 );
1554: e2 = new expr( G_CM, e2, temp );
1555: e2->tp = temp->tp;
1556: }
1557:
1558: if (t1==t2
1559: || ( (c1=t1->is_cl_obj())
1560: && (c2=t2->is_cl_obj())
1561: && (c1->tp==c2->tp)
1562: ))
1563: t = t1;
1564: else {
1565: r1 = t1->num_ptr(b);
1566: r2 = t2->num_ptr(b);
1567:
1568: if (r1=='P' && r2=='P') {
1569: Pptr p1 = t1->is_ptr();
1570: Pptr p2 = t2->is_ptr();
1571: //error('d',"p1 %t p2 %t",p1,p2);
1572: if ((c1 = p1->typ->is_cl_obj())
1573: && (c2 = p2->typ->is_cl_obj())) {
1574: Pclass cl1 = Pclass(c1->tp);
1575: Pclass cl2 = Pclass(c2->tp);
1576: if (cl1==cl2 || cl2->has_base(cl1)) {
1577: t = t1;
1578: goto caca;
1579: }
1580: else if (cl1->has_base(cl2)) {
1581: t = t2;
1582: goto caca;
1583: }
1584: }
1585: }
1586:
1587: if (r1==FCT && r2==FCT) { // fudge
1588: if (t1->check(t2,ASSIGN))
1589: error("badTs in ?:E: %t and %t",t1,t2);
1590: else if (Pfct(t1)->memof) error('s',"conditionalE with%t",t1);
1591: t = t1;
1592: }
1593: else
1594: nppromote(b);
1595: caca:
1596: //error('d',"?: t %t t1 %t t2 %t",t,t1,t2);
1597: if (t!=t1 && t->check(t1,0)) {
1598: PERM(t);
1599: e1 = new cast(t,e1);
1600: }
1601:
1602: if (t!=t2 && t->check(t2,0)) {
1603: PERM(t);
1604: e2 = new cast(t,e2);
1605: }
1606:
1607: Pptr pt = t->is_ptr();
1608: //if (pt && pt->base==PTR && pt->memof) error('s',"conditionalE with%t",t);
1609: if (pt && pt->base==PTR && pt->memof && MPTR == 0) error('s',"conditionalE with%t",t);
1610: }
1611: }
1612: break;
1613:
1614: case ASPLUS:
1615: r1 = t1->num_ptr(ASPLUS);
1616: r2 = t2->num_ptr(ASPLUS);
1617: nppromote(ASPLUS);
1618: goto ass;
1619:
1620: case ASMINUS:
1621: r1 = t1->num_ptr(ASMINUS);
1622: r2 = t2->num_ptr(ASMINUS);
1623: if (r2=='P' && r1!='P' && r1!='A') error("P -= nonP");
1624: nppromote(ASMINUS);
1625: goto ass;
1626:
1627: case ASMUL:
1628: case ASDIV:
1629: r1 = t1->numeric(b);
1630: r2 = t1->numeric(b);
1631: nppromote(b);
1632: goto ass;
1633:
1634: case ASMOD:
1635: r1 = t1->integral(ASMOD);
1636: r2 = t2->integral(ASMOD);
1637: nppromote(ASMOD);
1638: goto ass;
1639:
1640: case ASAND:
1641: case ASOR:
1642: case ASER:
1643: case ASLS:
1644: case ASRS:
1645: r1 = t1->integral(b);
1646: r2 = t2->integral(b);
1647: npcheck(b);
1648: t = int_type;
1649: goto ass;
1650: ass:
1651: if (r1='P' && t1->check(Pvoid_type,0)==0) error("%k of void*",b);
1652: tp = t;
1653: as_type = t; /* the type of the rhs */
1654: t2 = t;
1655:
1656: case ASSIGN:
1657: //error('d',"assign %k: %t %t %s",b,t1,t2,ignore_const?"ignore const":"");
1658: //error('d'," e1 %d %k e1 %d %k",e1,e1->base,e2,e2->base);
1659: if (ignore_const) { // handle static initializers
1660: // represented as assignments
1661: // ignore consts.
1662: tp = e1->tp;
1663: return this;
1664: }
1665:
1666: switch (e1->base) {
1667: case G_CM:
1668: case CM: // (a,b)=c => *(a,&b)=c
1669: {
1670: e1->e2 = new expr(G_ADDROF,0,e1->e2);
1671: e1->tp = 0;
1672: e1 = new expr(DEREF,e1,0);
1673: return typ(tbl);
1674: }
1675: case QUEST: // (a?b:c)=d => *(a?&b:&c)=c
1676: {
1677: e1->e1 = new expr(G_ADDROF,0,e1->e1);
1678: e1->e2 = new expr(G_ADDROF,0,e1->e2);
1679: e1->tp = 0;
1680: e1 = new expr(DEREF,e1,0);
1681: return typ(tbl);
1682: }
1683: case ASSIGN: // (a*=b)=c => a*=b,a=c
1684: case ASPLUS:
1685: case ASMINUS:
1686: case ASMUL:
1687: case ASDIV:
1688: case ASMOD:
1689: case ASAND:
1690: case ASOR:
1691: case ASER:
1692: case ASLS:
1693: case ASRS:
1694: {
1695: base = G_CM;
1696: nin++;
1697: if (e1->e1->not_simple()) error('s',"lvalue %k too complicated",b);
1698: nin--;
1699: Pexpr aa = new expr(e1->base,e1->e1,e1->e2);
1700: Pexpr bb = new expr(b,e1->e1,e2);
1701: e1 = aa;
1702: e2 = bb;
1703: return typ(tbl);
1704: }
1705: case INCR:
1706: case DECR: // ++a=b => ++a,a=b
1707: {
1708: if(!e1->e2) break ;
1709: base = G_CM;
1710: nin++;
1711: if (e1->e2->not_simple()) error('s',"lvalue %k too complicated",b);
1712: nin--;
1713: Pexpr aa = new expr(e1->base,0,e1->e2);
1714: Pexpr bb = new expr(b,e1->e2,e2);
1715: e1 = aa;
1716: e2 = bb;
1717: return typ(tbl);
1718: }
1719: case REF:
1720: {
1721: Pexpr r = e1;
1722: // hack to prevent
1723: // f().i = j
1724: // transformed into
1725: // ((t=f()),&t)->i = j
1726: if (r->e1->base==G_CM
1727: && r->e1->e2->base==G_ADDROF
1728: && r->e1->e2->e2->base==NAME) {
1729: char* s = r->e1->e2->e2->string;
1730: if (s[0]=='_' && s[1]=='_')
1731: error("left hand side not lvalue");
1732: }
1733: }
1734: }
1735:
1736: if (e1->lval(b) == 0) {
1737: tp = any_type;
1738: return this;
1739: }
1740: lkj:
1741: switch (t1->base) {
1742: case TYPE:
1743: t1 = t1->bname_type();
1744: goto lkj;
1745: case INT:
1746: case CHAR:
1747: case SHORT:
1748: // if (e2->base==ICON && e2->tp==long_type)
1749: // error('w',"long constant assigned to%k",t1->base);
1750: { Ptype t = e2->tp;
1751: csi:
1752: switch (t->base) {
1753: case TYPE:
1754: t = t->bname_type();
1755: goto csi;
1756: case LONG:
1757: case FLOAT:
1758: case DOUBLE:
1759: case LDOUBLE:
1760: error('w',"%t assigned to %t",e2->tp,t1);
1761: }
1762: }
1763: // no break
1764: case LONG:
1765: if (b==ASSIGN
1766: && Pbase(t1)->b_unsigned
1767: && e2->base==UMINUS
1768: && e2->e2->base==ICON)
1769: error('w',"negative assigned to unsigned");
1770: break;
1771: case PTR:
1772: if (b == ASSIGN) {
1773: //error('d',"ptr t1 %t %d %t",t1,t1->memptr(),t2);
1774: //?? if (t1->memptr() && t2->base!=OVERLOAD) break;
1775: e2 = ptr_init(Pptr(t1),e2,tbl);
1776: t2 = e2->tp;
1777: //error('d',"pchecked %d",Pchecked);
1778: if (Pchecked) {
1779: tp = e1->tp;
1780: return this;
1781: }
1782: }
1783: break;
1784: case COBJ:
1785: { Pname c1 = t1->is_cl_obj();
1786: // test of c1->tp necessary for ``fake classes''
1787: // _Sdd generated for vector assignemnts
1788: if (c1
1789: && c1->tp
1790: /* && Pclass(c1->tp)->memtbl->look("__as",0)==0*/) {
1791: //&& Pclass(c1->tp)->has_oper(ASSIGN)==0) {
1792: Pname c2 = t2->is_cl_obj();
1793: // error('d', "expr::typ: c1: %n c2: %n", c1, c2 );
1794: if (c1 != c2) {
1795: /*
1796: consider:
1797:
1798: struct A { A(B&); };
1799: struct B : A {};
1800:
1801: A aa;
1802: B bb;
1803:
1804: aa = bb; // aa.operator=(A(bb));
1805: // optimize to aa.A(bb) when possible
1806: // avoid temporary where aa = *(A*)&bb is legal
1807: */
1808: // error('d',"expr::typ c1 %n %d c2 %n %d",c1,c1?c1->tp:0,c2,c2?c2->tp:0);
1809: if (c2
1810: && c2->tp
1811: && can_coerce(t1,t2)==0
1812: //&& Pclass(c2->tp)->has_base(Pclass(c1->tp))
1813: //&& (1<is_unique_base(Pclass(c2->tp),c1->string,0))
1814: && (vcllist->clear(),vcllist=0,1<is_unique_base(Pclass(c2->tp),c1->string,0))
1815: && Pclass(c1->tp)->c_xref&(C_VBASE|C_VPTR|C_ASS)) {
1816: // error('d',"aaa");
1817: if (make_assignment(c1)) return try_to_overload(tbl);
1818: }
1819: // optimize
1820: else {
1821: e2 = new expr(ELIST,e2,0);
1822: e2 = new texpr(VALUE,t1,e2);
1823: if (Pclass(c1->tp)->has_dtor()==0 &&
1824: Pclass(c1->tp)->has_oper(ASSIGN)==0) {
1825: // optimize
1826: // error('d',"bbb");
1827: e2->e2 = e1;
1828: e2 = e2->typ(tbl);
1829: if (e2->base==DEREF && e2->e1->base==G_CALL ||
1830: e2->base==ASSIGN && e2->e1==e1) {
1831: // error('d',"ccc");
1832: *this = *e2;
1833: }
1834: tp = t1;
1835: return this;
1836: }
1837: return typ(tbl);
1838: }
1839: }
1840: // test of c1->tp necessary for ``fake classes''
1841: // _Sdd generated for vector assignemnts
1842: else if (c1->tp && Pclass(c1->tp)->c_xref&(C_VBASE|C_VPTR|C_ASS)) {
1843: if (make_assignment(c1)) return try_to_overload(tbl);
1844: }
1845: }
1846: (void) t1->tsizeof();
1847: break;
1848: }
1849: }
1850:
1851: //error('d',"check(%t,%t) -> %d",e1->tp,t2,try_to_coerce(t1,e2,"assignment",tbl));
1852: { Pexpr x = try_to_coerce(t1,e2,"assignment",tbl);
1853: if (x)
1854: e2 = x;
1855: else if (e1->tp->check(t2,ASSIGN))
1856: error("bad assignmentT:%t =%t",e1->tp,t2);
1857: else if ((t1 = t1->is_ptr()) && t1->memptr()) {
1858: if (t2 == zero_type) {
1859: Pexpr ee = new expr(ELIST,zero,zero);
1860: e2 = new expr(ILIST,ee,zero);
1861: }
1862: else if (t2->base==PTR && t2->memptr()) {
1863: // do nothing: structure assignment
1864: }
1865: else {
1866: Pexpr x = ptr_init(Pptr(t1),e2,tbl);
1867: if (x != e2) e2 = x;
1868: }
1869: }
1870: }
1871: t = e1->tp; // the type of the lhs
1872: break;
1873: case CM:
1874: case G_CM:
1875: t = t2;
1876: break;
1877: default:
1878: error('i',"unknown operator%k",b);
1879: }
1880:
1881: tp = t;
1882: return this;
1883: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.