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