Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030707111417

Diff

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