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