Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030707131705

Diff

Diff from 1.48 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/cc/ccom/trees.c

Annotated File View

ragge
1.1
1 # include "pass1.h"
ragge
1.9
2 # include "pass2.h"     /* for NOPREF */
ragge
1.1
3
4 # include <setjmp.h>
ragge
1.16
5 # include <stdarg.h>
6 # include <string.h>
ragge
1.1
7
ragge
1.30
8 int adebug = 0/* XXX 4.4 */
ragge
1.1
9
ragge
1.2
10 void chkpun(NODE *p);
11 int opact(NODE *p);
12 int moditype(TWORD);
ragge
1.45
13 static NODE *strargs(NODE *);
ragge
1.2
14
15 /* corrections when in violation of lint */
ragge
1.1
16
17 /*      some special actions, used in finding the type of nodes */
18 # define NCVT 01
19 # define PUN 02
20 # define TYPL 04
21 # define TYPR 010
22 # define TYMATCH 040
23 # define LVAL 0100
24 # define CVTO 0200
25 # define CVTL 0400
26 # define CVTR 01000
27 # define PTMATCH 02000
28 # define OTHER 04000
29 # define NCVTR 010000
30
ragge
1.34
31 #ifdef PCC_DEBUG
ragge
1.2
32 static void
ragge
1.30
33 printact(NODE *tint acts)     /* XXX 4.4  hela printact */
ragge
1.1
34 {
35         static struct actions {
36                 int     a_bit;
37                 char    *a_name;
38         } actions[] = {
39                 { PUN,          "PUN" },
40                 { CVTL,         "CVTL" },
41                 { CVTR,         "CVTR" },
42                 { TYPL,         "TYPL" },
43                 { TYPR,         "TYPR" },
44                 { TYMATCH,      "TYMATCH" },
45                 { PTMATCH,      "PTMATCH" },
46                 { LVAL,         "LVAL" },
47                 { CVTO,         "CVTO" },
48                 { NCVT,         "NCVT" },
49                 { OTHER,        "OTHER" },
50                 { NCVTR,        "NCVTR" },
51                 { 0 }
52         };
53         register struct actions *p;
54         char *sep = " ";
55
56         printf("actions");
57         for (p = actionsp->a_namep++)
58                 if (p->a_bit & acts) {
59                         printf("%s%s"sepp->a_name);
60                         sep = "|";
61                 }
62         if (!bdebug) {
63                 printf(" for:\n");
64                 fwalk(teprint0);
65         } else
66                 putchar('\n');
67 }
68 #endif
69
70 /* node conventions:
71
72         NAME:   rval>0 is stab index for external
73                 rval<0 is -inlabel number
74                 lval is offset in bits
75         ICON:   lval has the value
76                 rval has the STAB index, or - label number,
77                         if a name whose address is in the constant
78                 rval = NONAME means no name
79         REG:    rval is reg. identification cookie
80
81         */
82
ragge
1.30
83 int bdebug = 0;
84
ragge
1.1
85 NODE *
ragge
1.2
86 buildtree(int oNODE *lNODE *r)
87 {
88         NODE *p, *q;
89         int actions;
90         int opty;
91         struct symtab *sp;
92         NODE *lr, *ll;
ragge
1.23
93         char *name;
ragge
1.26
94         struct symtab **elem;
ragge
1.1
95
96 # ifndef BUG1
ragge
1.2
97         if (bdebug)
98                 printf("buildtree(%s, %p, %p)\n"opst[o], lr);
ragge
1.1
99 # endif
100         opty = optype(o);
101
102         /* check for constants */
103
ragge
1.22
104         ifopty == UTYPE && l->n_op == ICON ){
ragge
1.1
105
106                 switcho ){
107
108                 case NOT:
109                 case UNARY MINUS:
110                 case COMPL:
111                         ifconvallol ) ) return(l);
112                         break;
113
114                 }
ragge
1.44
115         } else ifo == UNARY MINUS && l->n_op == FCON ){
116                         ifl->n_type == FLOAT )
ragge
1.22
117                                 l->n_fcon = -l->n_fcon;
ragge
1.1
118                         else
ragge
1.22
119                                 l->n_dcon = -l->n_dcon;
ragge
1.1
120                         return(l);
121
ragge
1.44
122         } else ifo==QUEST && l->n_op==ICON ) {
ragge
1.41
123                 CONSZ c = l->n_lval;
124                 nfree(l);
125                 if (c) {
126                         tfree(r->n_right);
127                         l = r->n_left;
128                         nfree(r);
129                         return(l);
130                 } else {
131                         tfree(r->n_left);
132                         l = r->n_right;
133                         nfree(r);
134                         return(l);
ragge
1.1
135                 }
ragge
1.44
136         } else if( (o==ANDAND || o==OROR) && (l->n_op==ICON||r->n_op==ICON) )
137                 goto ccwarn;
ragge
1.1
138
ragge
1.22
139         else ifopty == BITYPE && l->n_op == ICON && r->n_op == ICON ){
ragge
1.1
140
141                 switcho ){
142
143                 case ULT:
144                 case UGT:
145                 case ULE:
146                 case UGE:
147                 case LT:
148                 case GT:
149                 case LE:
150                 case GE:
151                 case EQ:
ragge
1.48
152                 case NE:
ragge
1.1
153                 case ANDAND:
154                 case OROR:
155                 case CBRANCH:
156
157                 ccwarn:
158
159                 case PLUS:
160                 case MINUS:
161                 case MUL:
162                 case DIV:
163                 case MOD:
164                 case AND:
165                 case OR:
166                 case ER:
167                 case LS:
168                 case RS:
169                         ifconvallor ) ) {
ragge
1.41
170                                 nfree(r);
ragge
1.1
171                                 return(l);
ragge
1.44
172                         }
ragge
1.1
173                         break;
174                 }
ragge
1.44
175         } else if (opty == BITYPE && (l->n_op == FCON || l->n_op == ICON) &&
176             (r->n_op == FCON || r->n_op == ICON) && (o == PLUS || o == MINUS ||
177             o == MUL || o == DIV)) {
178                 switch(o){
179                 case PLUS:
180                 case MINUS:
181                 case MUL:
182                 case DIV:
183                         if (l->n_op == ICON)
184                                 l->n_dcon = l->n_lval;
185                         else if (l->n_type == FLOAT)
186                                 l->n_dcon = l->n_fcon;
187                         if (r->n_op == ICON)
188                                 r->n_dcon = r->n_lval;
189                         else if (r->n_type == FLOAT)
190                                 r->n_dcon = r->n_fcon;
191                         switch (o) {
192                         case PLUS:
193                                 l->n_dcon += r->n_dconbreak;
194                         case MINUS:
195                                 l->n_dcon -= r->n_dconbreak;
196                         case MUL:
197                                 l->n_dcon *= r->n_dconbreak;
198                         case DIV:
199                                 if (r->n_dcon == 0)
200                                         uerror("division by 0.");
201                                 else
202                                         l->n_dcon /= r->n_dcon;
203                         }
204                         l->n_op = FCON;
205                         l->n_type = DOUBLE;
206                         l->n_sue = MKSUE(DOUBLE);
207                         nfree(r);
208                         return(l);
ragge
1.1
209                 }
ragge
1.44
210         }
ragge
1.1
211
ragge
1.30
212         /* its real; we must make a new node */
ragge
1.1
213
ragge
1.26
214         p = block(olrINT0MKSUE(INT));
ragge
1.1
215
216         actions = opact(p);
ragge
1.35
217 #ifdef PCC_DEBUG
ragge
1.30
218         if (adebug)     /* XXX 4.4 */
ragge
1.1
219                 printact(pactions);
220 #endif
221
222         ifactions&LVAL ){ /* check left descendent */
ragge
1.22
223                 ifnotlval(p->n_left) ) {
ragge
1.30
224                         uerror"lvalue required" );
ragge
1.1
225                         }
226                 }
227
228         ifactions & NCVTR ){
ragge
1.22
229                 p->n_left = pconvertp->n_left );
ragge
1.1
230                 }
231         else if( !(actions & NCVT ) ){
232                 switchopty ){
233
234                 case BITYPE:
ragge
1.22
235                         p->n_right = pconvertp->n_right );
ragge
1.1
236                 case UTYPE:
ragge
1.22
237                         p->n_left = pconvertp->n_left );
ragge
1.1
238
239                         }
240                 }
241
ragge
1.7
242         if ((actions&PUN) && (o!=CAST||cflag))
ragge
1.1
243                 chkpun(p);
244
245         ifactions & (TYPL|TYPR) ){
246
ragge
1.22
247                 q = (actions&TYPL) ? p->n_left : p->n_right;
ragge
1.1
248
ragge
1.22
249                 p->n_type = q->n_type;
ragge
1.29
250                 p->n_df = q->n_df;
ragge
1.26
251                 p->n_sue = q->n_sue;
ragge
1.1
252                 }
253
254         ifactions & CVTL ) p = convertpCVTL );
255         ifactions & CVTR ) p = convertpCVTR );
256         ifactions & TYMATCH ) p = tymatch(p);
257         ifactions & PTMATCH ) p = ptmatch(p);
258
259         ifactions & OTHER ){
ragge
1.22
260                 l = p->n_left;
261                 r = p->n_right;
ragge
1.1
262
263                 switch(o){
264
265                 case NAME:
ragge
1.23
266                         sp = spname;
267                         if (sp->stype == UNDEF) {
268                                 uerror("%s undefined"sp->sname);
ragge
1.1
269                                 /* make p look reasonable */
ragge
1.26
270                                 p->n_type = INT;
271                                 p->n_sue = MKSUE(INT);
ragge
1.29
272                                 p->n_df = NULL;
ragge
1.23
273                                 p->n_sp = sp;
ragge
1.22
274                                 p->n_lval = 0;
ragge
1.23
275                                 defid(pSNULL);
ragge
1.1
276                                 break;
ragge
1.23
277                         }
ragge
1.22
278                         p->n_type = sp->stype;
ragge
1.29
279                         p->n_df = sp->sdf;
ragge
1.26
280                         p->n_sue = sp->ssue;
ragge
1.22
281                         p->n_lval = 0;
ragge
1.23
282                         p->n_sp = sp;
ragge
1.1
283                         /* special case: MOETY is really an ICON... */
ragge
1.23
284                         if (p->n_type == MOETY) {
285                                 p->n_sp = NULL;
286                                 p->n_lval = sp->soffset;
ragge
1.29
287                                 p->n_df = NULL;
ragge
1.22
288                                 p->n_type = ENUMTY;
289                                 p->n_op = ICON;
ragge
1.23
290                         }
ragge
1.1
291                         break;
292
293                 case STRING:
ragge
1.22
294                         p->n_op = NAME;
ragge
1.17
295 #ifdef CHAR_UNSIGNED
ragge
1.22
296                         p->n_type = UCHAR+ARY;
ragge
1.26
297                         p->n_sue = MKSUE(UCHAR);
ragge
1.17
298 #else
ragge
1.22
299                         p->n_type = CHAR+ARY;
ragge
1.26
300                         p->n_sue = MKSUE(CHAR);
ragge
1.17
301 #endif
ragge
1.22
302                         p->n_lval = 0;
ragge
1.23
303                         p->n_sp = NULL;
ragge
1.1
304                         break;
305
306                 case STREF:
307                         /* p->x turned into *(p+offset) */
308                         /* rhs must be a name; check correctness */
309
ragge
1.23
310                         /* Find member symbol struct */
311                         if (l->n_type != PTR+STRTY && l->n_type != PTR+UNIONTY){
312                                 uerror("struct or union required");
313                                 break;
314                         }
315
ragge
1.26
316                         if ((elem = l->n_sue->suelem) == NULL)
ragge
1.23
317                                 uerror("undefined struct or union");
318
319                         name = r->n_name;
ragge
1.26
320                         for (; *elem != NULLelem++) {
321                                 sp = *elem;
ragge
1.23
322                                 if (sp->sname == name)
323                                         break;
324                         }
ragge
1.26
325                         if (*elem == NULL)
ragge
1.23
326                                 uerror("member '%s' not declared"name);
327
328                         r->n_sp = sp;
329                         p = stref(p);
330                         break;
331
ragge
1.1
332                 case UNARY MUL:
ragge
1.41
333                         if (l->n_op == UNARY AND) {
334                                 nfree(p);
ragge
1.22
335                                 p = l->n_left;
ragge
1.41
336                                 nfree(l);
337                         }
ragge
1.22
338                         if( !ISPTR(l->n_type))uerror("illegal indirection");
339                         p->n_type = DECREF(l->n_type);
ragge
1.29
340                         p->n_df = l->n_df;
ragge
1.26
341                         p->n_sue = l->n_sue;
ragge
1.1
342                         break;
343
344                 case UNARY AND:
ragge
1.22
345                         switchl->n_op ){
ragge
1.1
346
347                         case UNARY MUL:
ragge
1.41
348                                 nfree(p);
ragge
1.22
349                                 p = l->n_left;
ragge
1.41
350                                 nfree(l);
ragge
1.1
351                         case NAME:
ragge
1.22
352                                 p->n_type = INCREFl->n_type );
ragge
1.29
353                                 p->n_df = l->n_df;
ragge
1.26
354                                 p->n_sue = l->n_sue;
ragge
1.1
355                                 break;
356
357                         case COMOP:
ragge
1.41
358                                 nfree(p);
ragge
1.22
359                                 lr = buildtreeUNARY ANDl->n_rightNIL );
360                                 p = buildtreeCOMOPl->n_leftlr );
ragge
1.41
361                                 nfree(l);
ragge
1.1
362                                 break;
363
364                         case QUEST:
ragge
1.22
365                                 lr = buildtreeUNARY ANDl->n_right->n_rightNIL );
366                                 ll = buildtreeUNARY ANDl->n_right->n_leftNIL );
ragge
1.41
367                                 nfree(p); nfree(l->n_right);
ragge
1.22
368                                 p = buildtreeQUESTl->n_leftbuildtreeCOLONlllr ) );
ragge
1.41
369                                 nfree(l);
ragge
1.1
370                                 break;
371
ragge
1.30
372 # ifdef ADDROREG        /* XXX 4.4  addroreg */
ragge
1.1
373                         case OREG:
374                                 /* OREG was built in clocal()
375                                  * for an auto or formal parameter
376                                  * now its address is being taken
377                                  * local code must unwind it
378                                  * back to PLUS/MINUS REG ICON
379                                  * according to local conventions
380                                  */
ragge
1.41
381                                 nfree(p);
ragge
1.1
382                                 p = addroregl );
383                                 break;
384
385 # endif
386                         default:
ragge
1.22
387                                 uerror("unacceptable operand of &: %d"l->n_op );
ragge
1.1
388                                 break;
389                                 }
390                         break;
391
392                 case LS:
ragge
1.30
393                 case RS:        /* XXX 4.4 satsen */
ragge
1.22
394                         ifl->n_type == CHAR || l->n_type == SHORT )
395                                 p->n_type = INT;
396                         else ifl->n_type == UCHAR || l->n_type == USHORT )
397                                 p->n_type = UNSIGNED;
ragge
1.1
398                         else
ragge
1.22
399                                 p->n_type = l->n_type;
ragge
1.1
400                 case ASG LS:
401                 case ASG RS:
ragge
1.22
402                         ifr->n_type != INT )
ragge
1.26
403                                 p->n_right = r = makety(rINT0MKSUE(INT));
ragge
1.1
404                         break;
405
406                 case RETURN:
407                 case ASSIGN:
408                 case CAST:
409                         /* structure assignment */
410                         /* take the addresses of the two sides; then make an
ragge
1.2
411                          * operator using STASG and
412                          * the addresses of left and right */
ragge
1.1
413
414                         {
ragge
1.26
415                                 struct suedef *sue;
ragge
1.2
416                                 TWORD t;
ragge
1.29
417                                 union dimfun *d;
ragge
1.1
418
ragge
1.26
419                                 if (l->n_sue != r->n_sue)
420                                         uerror("assignment of different structures");
ragge
1.1
421
ragge
1.26
422                                 r = buildtree(UNARY ANDrNIL);
ragge
1.22
423                                 t = r->n_type;
ragge
1.29
424                                 d = r->n_df;
ragge
1.26
425                                 sue = r->n_sue;
ragge
1.1
426
ragge
1.28
427                                 l = block(STASGlrtdsue);
ragge
1.1
428
429                                 ifo == RETURN ){
ragge
1.41
430                                         nfree(p);
ragge
1.1
431                                         p = l;
432                                         break;
ragge
1.28
433                                 }
ragge
1.1
434
ragge
1.22
435                                 p->n_op = UNARY MUL;
436                                 p->n_left = l;
437                                 p->n_right = NIL;
ragge
1.1
438                                 break;
439                                 }
440                 case COLON:
441                         /* structure colon */
442
ragge
1.26
443                         if (l->n_sue != r->n_sue)
444                                 uerror"type clash in conditional" );
ragge
1.1
445                         break;
446
447                 case CALL:
ragge
1.45
448                         p->n_right = r = strargs(p->n_right);
ragge
1.1
449                 case UNARY CALL:
ragge
1.23
450                         if (!ISPTR(l->n_type))
451                                 uerror("illegal function");
ragge
1.22
452                         p->n_type = DECREF(l->n_type);
ragge
1.23
453                         if (!ISFTN(p->n_type))
454                                 uerror("illegal function");
455                         p->n_type = DECREF(p->n_type);
ragge
1.29
456                         p->n_df = l->n_df;
ragge
1.26
457                         p->n_sue = l->n_sue;
ragge
1.23
458                         if (l->n_op == UNARY AND && l->n_left->n_op == NAME &&
459                             l->n_left->n_sp != NULL && l->n_left->n_sp != NULL &&
460                             (l->n_left->n_sp->sclass == FORTRAN ||
461                             l->n_left->n_sp->sclass == UFORTRAN)) {
ragge
1.22
462                                 p->n_op += (FORTCALL-CALL);
ragge
1.23
463                         }
464                         if (p->n_type == STRTY || p->n_type == UNIONTY) {
ragge
1.1
465                                 /* function returning structure */
466                                 /*  make function really return ptr to str., with * */
467
ragge
1.22
468                                 p->n_op += STCALL-CALL;
ragge
1.23
469                                 p->n_type = INCREF(p->n_type);
470                                 p = buildtree(UNARY MULpNIL);
ragge
1.1
471
472                                 }
473                         break;
474
475                 default:
476                         cerror"other code %d"o );
477                         }
478
479                 }
480
ragge
1.11
481         /*
482          * Allow (void)0 casts.
483          * XXX - anything on the right side must be possible to cast.
484          * XXX - remove void types further on.
485          */
ragge
1.22
486         if (p->n_op == CAST && p->n_type == UNDEF &&
487             p->n_right->n_op == ICON)
488                 p->n_right->n_type = UNDEF;
ragge
1.11
489
ragge
1.1
490         ifactions & CVTO ) p = oconvert(p);
491         p = clocal(p);
492
ragge
1.30
493 #ifdef PCC_DEBUG
ragge
1.1
494         ifbdebug ) fwalkpeprint0 );
ragge
1.30
495 #endif
ragge
1.1
496
497         return(p);
498
499         }
500
501 NODE *
ragge
1.45
502 strargsp ) register NODE *p;  { /* rewrite structure flavored arguments */
ragge
1.1
503
ragge
1.45
504         ifp->n_op == CM ){
505                 p->n_left = strargsp->n_left );
506                 p->n_right = strargsp->n_right );
ragge
1.1
507                 returnp );
508                 }
509
ragge
1.22
510         ifp->n_type == STRTY || p->n_type == UNIONTY ){
ragge
1.29
511                 p = block(STARGpNILp->n_typep->n_dfp->n_sue);
ragge
1.22
512                 p->n_left = buildtreeUNARY ANDp->n_leftNIL );
ragge
1.1
513                 p = clocal(p);
514                 }
515         returnp );
ragge
1.2
516 }
ragge
1.1
517
ragge
1.2
518 /*
519  * apply the op o to the lval part of p; if binary, rhs is val
520  */
521 int
522 conval(NODE *pint oNODE *q)
523 {
ragge
1.1
524         int iu;
525         CONSZ val;
526
ragge
1.22
527         val = q->n_lval;
528         u = ISUNSIGNED(p->n_type) || ISUNSIGNED(q->n_type);
ragge
1.1
529         ifu && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE);
530
ragge
1.23
531         if (p->n_sp != NULL && q->n_sp != NULL)
532                 return(0);
533         if (q->n_sp != NULL && o != PLUS)
534                 return(0);
535         if (p->n_sp != NULL && o != PLUS && o != MINUS)
536                 return(0);
ragge
1.1
537
538         switcho ){
539
540         case PLUS:
ragge
1.22
541                 p->n_lval += val;
ragge
1.23
542                 if (p->n_sp == NULL) {
ragge
1.22
543                         p->n_rval = q->n_rval;
544                         p->n_type = q->n_type;
ragge
1.23
545                 }
ragge
1.1
546                 break;
547         case MINUS:
ragge
1.22
548                 p->n_lval -= val;
ragge
1.1
549                 break;
550         case MUL:
ragge
1.22
551                 p->n_lval *= val;
ragge
1.1
552                 break;
553         case DIV:
ragge
1.46
554                 if (val == 0)
555                         uerror("division by 0");
556                 else 
557                         p->n_lval /= val;
ragge
1.1
558                 break;
559         case MOD:
ragge
1.46
560                 if (val == 0)
561                         uerror("division by 0");
562                 else 
563                         p->n_lval %= val;
ragge
1.1
564                 break;
565         case AND:
ragge
1.22
566                 p->n_lval &= val;
ragge
1.1
567                 break;
568         case OR:
ragge
1.22
569                 p->n_lval |= val;
ragge
1.1
570                 break;
571         case ER:
ragge
1.22
572                 p->n_lval ^= val;
ragge
1.1
573                 break;
574         case LS:
575                 i = val;
ragge
1.22
576                 p->n_lval = p->n_lval << i;
ragge
1.1
577                 break;
578         case RS:
579                 i = val;
ragge
1.46
580                 p->n_lval = p->n_lval >> i;
ragge
1.1
581                 break;
582
583         case UNARY MINUS:
ragge
1.22
584                 p->n_lval = - p->n_lval;
ragge
1.1
585                 break;
586         case COMPL:
ragge
1.22
587                 p->n_lval = ~p->n_lval;
ragge
1.1
588                 break;
589         case NOT:
ragge
1.22
590                 p->n_lval = !p->n_lval;
ragge
1.1
591                 break;
592         case LT:
ragge
1.22
593                 p->n_lval = p->n_lval < val;
ragge
1.1
594                 break;
595         case LE:
ragge
1.22
596                 p->n_lval = p->n_lval <= val;
ragge
1.1
597                 break;
598         case GT:
ragge
1.22
599                 p->n_lval = p->n_lval > val;
ragge
1.1
600                 break;
601         case GE:
ragge
1.22
602                 p->n_lval = p->n_lval >= val;
ragge
1.1
603                 break;
604         case ULT:
ragge
1.46
605                 p->n_lval = (p->n_lval-val)<0;
ragge
1.1
606                 break;
607         case ULE:
ragge
1.46
608                 p->n_lval = (p->n_lval-val)<=0;
ragge
1.1
609                 break;
610         case UGT:
ragge
1.46
611                 p->n_lval = (p->n_lval-val)>=0;
ragge
1.1
612                 break;
613         case UGE:
ragge
1.46
614                 p->n_lval = (p->n_lval-val)>0;
ragge
1.1
615                 break;
616         case EQ:
ragge
1.22
617                 p->n_lval = p->n_lval == val;
ragge
1.1
618                 break;
619         case NE:
ragge
1.22
620                 p->n_lval = p->n_lval != val;
ragge
1.1
621                 break;
622         default:
623                 return(0);
624                 }
625         return(1);
626         }
627
ragge
1.7
628 /*
629  * Checks p for the existance of a pun.  This is called when the op of p
630  * is ASSIGN, RETURN, CAST, COLON, or relational.
631  * One case is when enumerations are used: this applies only to lint.
632  * In the other case, one operand is a pointer, the other integer type
633  * we check that this integer is in fact a constant zero...
634  * in the case of ASSIGN, any assignment of pointer to integer is illegal
635  * this falls out, because the LHS is never 0.
636  */
ragge
1.2
637 void
ragge
1.7
638 chkpun(NODE *p)
639 {
ragge
1.29
640         union dimfun *d1, *d2;
ragge
1.2
641         NODE *q;
ragge
1.47
642         int t1t2;
ragge
1.1
643
ragge
1.22
644         t1 = p->n_left->n_type;
645         t2 = p->n_right->n_type;
ragge
1.1
646
ragge
1.7
647         /* check for enumerations */
648         if (t1==ENUMTY || t2==ENUMTY) {
ragge
1.47
649                 iflogopp->n_op ) && p->n_op != EQ && p->n_op != NE ) {
650                         uerror"comparison of enums" );
651                         return;
652                         }
ragge
1.7
653                 if (t1==ENUMTY && t2==ENUMTY) {
ragge
1.26
654                         if (p->n_left->n_sue!=p->n_right->n_sue)
ragge
1.7
655                                 werror("enumeration type clash, "
ragge
1.47
656                                     "operator %s"opst[p->n_op]);
ragge
1.1
657                         return;
658                 }
ragge
1.7
659         }
ragge
1.1
660
ragge
1.47
661         ifISPTR(t1) || ISARY(t1) ) q = p->n_right;
662         else q = p->n_left;
ragge
1.1
663
ragge
1.47
664         if ( !ISPTR(q->n_type) && !ISARY(q->n_type) ){
ragge
1.22
665                 if (q->n_op != ICON || q->n_lval != 0)
ragge
1.47
666                         werror("illegal combination of pointer and integer");
667         } else {
668                 d1 = p->n_left->n_df;
669                 d2 = p->n_right->n_df;
670                 for (;;) {
671                         ift1 == t2 ) {;
672                                 if (p->n_left->n_sue != p->n_right->n_sue) {
673                                         werror("illegal structure pointer combination");
674                                 }
ragge
1.1
675                                 return;
ragge
1.5
676                         }
ragge
1.47
677                         if (ISARY(t1) || ISPTR(t1) ) {
678                                 if( !ISARY(t2) && !ISPTR(t2) ) break;
679                                 if (ISARY(t1) && ISARY(t2) && d1->ddim != d2->ddim) {
680                                         werror("illegal array size combination");
681                                         return;
682                                 }
683                                 ifISARY(t1) ) ++d1;
684                                 ifISARY(t2) ) ++d2; ++d2;
685                         } else if (ISFTN(t1)) {
686                                 if (chkftn(d1->dfund2->dfun)) {
687                                         werror("illegal function "
688                                             "pointer combination");
689                                         return;
690                                 }
691                                 ++d1;
692                                 ++d2;
693                         } else break;
694                         t1 = DECREF(t1);
695                         t2 = DECREF(t2);
696                 }
697                 werror("illegal pointer combination");
ragge
1.1
698         }
ragge
1.5
699 }
ragge
1.1
700
701 NODE *
ragge
1.10
702 stref(NODE *p)
703 {
ragge
1.41
704         NODE *r;
ragge
1.26
705         struct suedef *sue;
ragge
1.29
706         union dimfun *d;
ragge
1.1
707         TWORD t;
ragge
1.30
708         int dscalign/* XXX 4.4 */
ragge
1.1
709         OFFSZ off;
710         register struct symtab *q;
711
712         /* make p->x */
713         /* this is also used to reference automatic variables */
714
ragge
1.23
715         q = p->n_right->n_sp;
ragge
1.41
716         nfree(p->n_right);
717         r = p->n_left;
718         nfree(p);
719         p = pconvert(r);
ragge
1.1
720
721         /* make p look like ptr to x */
722
ragge
1.22
723         if (!ISPTR(p->n_type))
724                 p->n_type = PTR+UNIONTY;
ragge
1.1
725
ragge
1.10
726         t = INCREF(q->stype);
ragge
1.29
727         d = q->sdf;
ragge
1.26
728         sue = q->ssue;
ragge
1.1
729
ragge
1.26
730         p = makety(ptdsue);
ragge
1.1
731
732         /* compute the offset to be added */
733
ragge
1.23
734         off = q->soffset;
ragge
1.1
735         dsc = q->sclass;
736
ragge
1.10
737         if (dsc & FIELD) {  /* normalize offset */
ragge
1.30
738                 align = ALINT;  /* XXX 4.4 */
ragge
1.26
739                 sue = MKSUE(INT);
ragge
1.30
740                 off = (off/align)*align;        /* XXX 4.4 */
ragge
1.10
741         }
742         if (off != 0)
ragge
1.26
743                 p = clocal(block(PLUSpoffcon(offtdsue), tdsue));
ragge
1.1
744
ragge
1.10
745         p = buildtree(UNARY MULpNIL);
ragge
1.1
746
747         /* if field, build field info */
748
ragge
1.10
749         if (dsc & FIELD) {
ragge
1.26
750                 p = block(FLDpNILq->stype0q->ssue);
ragge
1.23
751                 p->n_rval = PKFIELD(dsc&FLDSIZq->soffset%align);
ragge
1.10
752         }
ragge
1.1
753
ragge
1.19
754         p = clocal(p);
755         return p;
ragge
1.10
756 }
ragge
1.1
757
ragge
1.2
758 int
ragge
1.1
759 notlval(pregister NODE *p; {
760
761         /* return 0 if p an lvalue, 1 otherwise */
762
763         again:
764
ragge
1.22
765         switchp->n_op ){
ragge
1.1
766
767         case FLD:
ragge
1.22
768                 p = p->n_left;
ragge
1.1
769                 goto again;
770
ragge
1.30
771         case UNARY MUL/* XXX 4.4 */
ragge
1.1
772                 /* fix the &(a=b) bug, given that a and b are structures */
ragge
1.22
773                 ifp->n_left->n_op == STASG ) return1 );
ragge
1.1
774                 /* and the f().a bug, given that f returns a structure */
ragge
1.22
775                 ifp->n_left->n_op == UNARY STCALL ||
776                     p->n_left->n_op == STCALL ) return1 );
ragge
1.1
777         case NAME:
778         case OREG:
ragge
1.22
779                 ifISARY(p->n_type) || ISFTN(p->n_type) ) return(1);
ragge
1.1
780         case REG:
781                 return(0);
782
783         default:
784                 return(1);
785
786                 }
787
788         }
ragge
1.23
789 /* make a constant node with value i */
ragge
1.1
790 NODE *
ragge
1.23
791 bcon(int i)
792 {
ragge
1.1
793         register NODE *p;
794
ragge
1.26
795         p = block(ICONNILNILINT0MKSUE(INT));
ragge
1.22
796         p->n_lval = i;
ragge
1.23
797         p->n_sp = NULL;
798         return(clocal(p));
799 }
ragge
1.1
800
801 NODE *
ragge
1.10
802 bpsize(NODE *p)
803 {
ragge
1.29
804         return(offcon(psize(p), p->n_typep->n_dfp->n_sue));
ragge
1.10
805 }
ragge
1.1
806
ragge
1.10
807 /*
808  * p is a node of type pointer; psize returns the
809  * size of the thing pointed to
810  */
ragge
1.1
811 OFFSZ
ragge
1.10
812 psize(NODE *p)
813 {
814
ragge
1.22
815         if (!ISPTR(p->n_type)) {
ragge
1.10
816                 uerror("pointer required");
817                 return(SZINT);
818         }
ragge
1.1
819         /* note: no pointers to fields */
ragge
1.29
820         return(tsize(DECREF(p->n_type), p->n_dfp->n_sue));
ragge
1.10
821 }
ragge
1.1
822
ragge
1.10
823 /*
824  * convert an operand of p
825  * f is either CVTL or CVTR
826  * operand has type int, and is converted by the size of the other side
827  */
ragge
1.1
828 NODE *
ragge
1.10
829 convert(NODE *pint f)
830 {
831         NODE *q, *r, *s;
ragge
1.1
832
ragge
1.22
833         q = (f == CVTL) ? p->n_left : p->n_right;
ragge
1.1
834
ragge
1.22
835         s = bpsize(f == CVTL ? p->n_right : p->n_left);
ragge
1.26
836         r = block(PMCONVqsINT0MKSUE(INT));
ragge
1.1
837         r = clocal(r);
ragge
1.13
838         /*
839          * Indexing is only allowed with integer arguments, so insert
840          * SCONV here if arg is not an integer.
841          * XXX - complain?
842          */
ragge
1.22
843         if (r->n_type != INT)
ragge
1.26
844                 r = clocal(block(SCONVrNILINT0MKSUE(INT)));
ragge
1.10
845         if (f == CVTL)
ragge
1.22
846                 p->n_left = r;
ragge
1.1
847         else
ragge
1.22