Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030707142340

Diff

Diff from 1.51 to:

Annotations

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

Annotated File View

ragge
1.51
1 /*      $Id: trees.c,v 1.51 2003/07/07 14:23:40 ragge Exp $     */
2 /*
3  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 /*
30  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
31  *
32  * Redistribution and use in source and binary forms, with or without
33  * modification, are permitted provided that the following conditions
34  * are met:
35  *
36  * Redistributions of source code and documentation must retain the above
37  * copyright notice, this list of conditions and the following disclaimer.
38  * Redistributions in binary form must reproduce the above copyright
39  * notice, this list of conditionsand the following disclaimer in the
40  * documentation and/or other materials provided with the distribution.
41  * All advertising materials mentioning features or use of this software
42  * must display the following acknowledgement:
43  *      This product includes software developed or owned by Caldera
44  *      International, Inc.
45  * Neither the name of Caldera International, Inc. nor the names of other
46  * contributors may be used to endorse or promote products derived from
47  * this software without specific prior written permission.
48  *
49  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
50  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
51  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
52  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
53  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
54  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
56  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
58  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
59  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
60  * POSSIBILITY OF SUCH DAMAGE.
61  */
62 /*
63  * Some of the changes from 32V include:
64  * - Understand "void" as type.
65  * - Handle enums as ints everywhere.
66  */
67
ragge
1.1
68 # include "pass1.h"
ragge
1.51
69 # include "pass2.h"
ragge
1.1
70
ragge
1.16
71 # include <stdarg.h>
ragge
1.1
72
ragge
1.51
73 static void chkpun(NODE *p);
74 static int opact(NODE *p);
75 static int moditype(TWORD);
ragge
1.45
76 static NODE *strargs(NODE *);
ragge
1.2
77
78 /* corrections when in violation of lint */
ragge
1.1
79
80 /*      some special actions, used in finding the type of nodes */
81 # define NCVT 01
82 # define PUN 02
83 # define TYPL 04
84 # define TYPR 010
85 # define TYMATCH 040
86 # define LVAL 0100
87 # define CVTO 0200
88 # define CVTL 0400
89 # define CVTR 01000
90 # define PTMATCH 02000
91 # define OTHER 04000
92 # define NCVTR 010000
93
94 /* node conventions:
95
96         NAME:   rval>0 is stab index for external
97                 rval<0 is -inlabel number
98                 lval is offset in bits
99         ICON:   lval has the value
100                 rval has the STAB index, or - label number,
101                         if a name whose address is in the constant
102                 rval = NONAME means no name
103         REG:    rval is reg. identification cookie
104
105         */
106
ragge
1.30
107 int bdebug = 0;
108
ragge
1.1
109 NODE *
ragge
1.2
110 buildtree(int oNODE *lNODE *r)
111 {
112         NODE *p, *q;
113         int actions;
114         int opty;
115         struct symtab *sp;
116         NODE *lr, *ll;
ragge
1.23
117         char *name;
ragge
1.26
118         struct symtab **elem;
ragge
1.1
119
120 # ifndef BUG1
ragge
1.2
121         if (bdebug)
122                 printf("buildtree(%s, %p, %p)\n"opst[o], lr);
ragge
1.1
123 # endif
124         opty = optype(o);
125
126         /* check for constants */
127
ragge
1.22
128         ifopty == UTYPE && l->n_op == ICON ){
ragge
1.1
129
130                 switcho ){
131
132                 case NOT:
133                 case UNARY MINUS:
134                 case COMPL:
135                         ifconvallol ) ) return(l);
136                         break;
137
138                 }
ragge
1.44
139         } else ifo == UNARY MINUS && l->n_op == FCON ){
140                         ifl->n_type == FLOAT )
ragge
1.22
141                                 l->n_fcon = -l->n_fcon;
ragge
1.1
142                         else
ragge
1.22
143                                 l->n_dcon = -l->n_dcon;
ragge
1.1
144                         return(l);
145
ragge
1.44
146         } else ifo==QUEST && l->n_op==ICON ) {
ragge
1.41
147                 CONSZ c = l->n_lval;
148                 nfree(l);
149                 if (c) {
150                         tfree(r->n_right);
151                         l = r->n_left;
152                         nfree(r);
153                         return(l);
154                 } else {
155                         tfree(r->n_left);
156                         l = r->n_right;
157                         nfree(r);
158                         return(l);
ragge
1.1
159                 }
ragge
1.44
160         } else if( (o==ANDAND || o==OROR) && (l->n_op==ICON||r->n_op==ICON) )
161                 goto ccwarn;
ragge
1.1
162
ragge
1.22
163         else ifopty == BITYPE && l->n_op == ICON && r->n_op == ICON ){
ragge
1.1
164
165                 switcho ){
166
167                 case ULT:
168                 case UGT:
169                 case ULE:
170                 case UGE:
171                 case LT:
172                 case GT:
173                 case LE:
174                 case GE:
175                 case EQ:
ragge
1.48
176                 case NE:
ragge
1.1
177                 case ANDAND:
178                 case OROR:
179                 case CBRANCH:
180
181                 ccwarn:
182
183                 case PLUS:
184                 case MINUS:
185                 case MUL:
186                 case DIV:
187                 case MOD:
188                 case AND:
189                 case OR:
190                 case ER:
191                 case LS:
192                 case RS:
193                         ifconvallor ) ) {
ragge
1.41
194                                 nfree(r);
ragge
1.1
195                                 return(l);
ragge
1.44
196                         }
ragge
1.1
197                         break;
198                 }
ragge
1.44
199         } else if (opty == BITYPE && (l->n_op == FCON || l->n_op == ICON) &&
200             (r->n_op == FCON || r->n_op == ICON) && (o == PLUS || o == MINUS ||
201             o == MUL || o == DIV)) {
202                 switch(o){
203                 case PLUS:
204                 case MINUS:
205                 case MUL:
206                 case DIV:
207                         if (l->n_op == ICON)
208                                 l->n_dcon = l->n_lval;
209                         else if (l->n_type == FLOAT)
210                                 l->n_dcon = l->n_fcon;
211                         if (r->n_op == ICON)
212                                 r->n_dcon = r->n_lval;
213                         else if (r->n_type == FLOAT)
214                                 r->n_dcon = r->n_fcon;
215                         switch (o) {
216                         case PLUS:
217                                 l->n_dcon += r->n_dconbreak;
218                         case MINUS:
219                                 l->n_dcon -= r->n_dconbreak;
220                         case MUL:
221                                 l->n_dcon *= r->n_dconbreak;
222                         case DIV:
223                                 if (r->n_dcon == 0)
224                                         uerror("division by 0.");
225                                 else
226                                         l->n_dcon /= r->n_dcon;
227                         }
228                         l->n_op = FCON;
229                         l->n_type = DOUBLE;
230                         l->n_sue = MKSUE(DOUBLE);
231                         nfree(r);
232                         return(l);
ragge
1.1
233                 }
ragge
1.44
234         }
ragge
1.1
235
ragge
1.30
236         /* its real; we must make a new node */
ragge
1.1
237
ragge
1.26
238         p = block(olrINT0MKSUE(INT));
ragge
1.1
239
240         actions = opact(p);
241
242         ifactions&LVAL ){ /* check left descendent */
ragge
1.22
243                 ifnotlval(p->n_left) ) {
ragge
1.30
244                         uerror"lvalue required" );
ragge
1.1
245                         }
246                 }
247
248         ifactions & NCVTR ){
ragge
1.22
249                 p->n_left = pconvertp->n_left );
ragge
1.1
250                 }
251         else if( !(actions & NCVT ) ){
252                 switchopty ){
253
254                 case BITYPE:
ragge
1.22
255                         p->n_right = pconvertp->n_right );
ragge
1.1
256                 case UTYPE:
ragge
1.22
257                         p->n_left = pconvertp->n_left );
ragge
1.1
258
259                         }
260                 }
261
ragge
1.7
262         if ((actions&PUN) && (o!=CAST||cflag))
ragge
1.1
263                 chkpun(p);
264
265         ifactions & (TYPL|TYPR) ){
266
ragge
1.22
267                 q = (actions&TYPL) ? p->n_left : p->n_right;
ragge
1.1
268
ragge
1.22
269                 p->n_type = q->n_type;
ragge
1.29
270                 p->n_df = q->n_df;
ragge
1.26
271                 p->n_sue = q->n_sue;
ragge
1.1
272                 }
273
274         ifactions & CVTL ) p = convertpCVTL );
275         ifactions & CVTR ) p = convertpCVTR );
276         ifactions & TYMATCH ) p = tymatch(p);
277         ifactions & PTMATCH ) p = ptmatch(p);
278
279         ifactions & OTHER ){
ragge
1.22
280                 l = p->n_left;
281                 r = p->n_right;
ragge
1.1
282
283                 switch(o){
284
285                 case NAME:
ragge
1.23
286                         sp = spname;
287                         if (sp->stype == UNDEF) {
288                                 uerror("%s undefined"sp->sname);
ragge
1.1
289                                 /* make p look reasonable */
ragge
1.26
290                                 p->n_type = INT;
291                                 p->n_sue = MKSUE(INT);
ragge
1.29
292                                 p->n_df = NULL;
ragge
1.23
293                                 p->n_sp = sp;
ragge
1.22
294                                 p->n_lval = 0;
ragge
1.23
295                                 defid(pSNULL);
ragge
1.1
296                                 break;
ragge
1.23
297                         }
ragge
1.22
298                         p->n_type = sp->stype;
ragge
1.29
299                         p->n_df = sp->sdf;
ragge
1.26
300                         p->n_sue = sp->ssue;
ragge
1.22
301                         p->n_lval = 0;
ragge
1.23
302                         p->n_sp = sp;
ragge
1.1
303                         /* special case: MOETY is really an ICON... */
ragge
1.23
304                         if (p->n_type == MOETY) {
305                                 p->n_sp = NULL;
306                                 p->n_lval = sp->soffset;
ragge
1.29
307                                 p->n_df = NULL;
ragge
1.22
308                                 p->n_type = ENUMTY;
309                                 p->n_op = ICON;
ragge
1.23
310                         }
ragge
1.1
311                         break;
312
313                 case STRING:
ragge
1.22
314                         p->n_op = NAME;
ragge
1.17
315 #ifdef CHAR_UNSIGNED
ragge
1.22
316                         p->n_type = UCHAR+ARY;
ragge
1.26
317                         p->n_sue = MKSUE(UCHAR);
ragge
1.17
318 #else
ragge
1.22
319                         p->n_type = CHAR+ARY;
ragge
1.26
320                         p->n_sue = MKSUE(CHAR);
ragge
1.17
321 #endif
ragge
1.22
322                         p->n_lval = 0;
ragge
1.23
323                         p->n_sp = NULL;
ragge
1.1
324                         break;
325
326                 case STREF:
327                         /* p->x turned into *(p+offset) */
328                         /* rhs must be a name; check correctness */
329
ragge
1.23
330                         /* Find member symbol struct */
331                         if (l->n_type != PTR+STRTY && l->n_type != PTR+UNIONTY){
332                                 uerror("struct or union required");
333                                 break;
334                         }
335
ragge
1.26
336                         if ((elem = l->n_sue->suelem) == NULL)
ragge
1.23
337                                 uerror("undefined struct or union");
338
339                         name = r->n_name;
ragge
1.26
340                         for (; *elem != NULLelem++) {
341                                 sp = *elem;
ragge
1.23
342                                 if (sp->sname == name)
343                                         break;
344                         }
ragge
1.26
345                         if (*elem == NULL)
ragge
1.23
346                                 uerror("member '%s' not declared"name);
347
348                         r->n_sp = sp;
349                         p = stref(p);
350                         break;
351
ragge
1.1
352                 case UNARY MUL:
ragge
1.41
353                         if (l->n_op == UNARY AND) {
354                                 nfree(p);
ragge
1.22
355                                 p = l->n_left;
ragge
1.41
356                                 nfree(l);
357                         }
ragge
1.22
358                         if( !ISPTR(l->n_type))uerror("illegal indirection");
359                         p->n_type = DECREF(l->n_type);
ragge
1.29
360                         p->n_df = l->n_df;
ragge
1.26
361                         p->n_sue = l->n_sue;
ragge
1.1
362                         break;
363
364                 case UNARY AND:
ragge
1.22
365                         switchl->n_op ){
ragge
1.1
366
367                         case UNARY MUL:
ragge
1.41
368                                 nfree(p);
ragge
1.22
369                                 p = l->n_left;
ragge
1.41
370                                 nfree(l);
ragge
1.1
371                         case NAME:
ragge
1.22
372                                 p->n_type = INCREFl->n_type );
ragge
1.29
373                                 p->n_df = l->n_df;
ragge
1.26
374                                 p->n_sue = l->n_sue;
ragge
1.1
375                                 break;
376
377                         case COMOP:
ragge
1.41
378                                 nfree(p);
ragge
1.22
379                                 lr = buildtreeUNARY ANDl->n_rightNIL );
380                                 p = buildtreeCOMOPl->n_leftlr );
ragge
1.41
381                                 nfree(l);
ragge
1.1
382                                 break;
383
384                         case QUEST:
ragge
1.22
385                                 lr = buildtreeUNARY ANDl->n_right->n_rightNIL );
386                                 ll = buildtreeUNARY ANDl->n_right->n_leftNIL );
ragge
1.41
387                                 nfree(p); nfree(l->n_right);
ragge
1.22
388                                 p = buildtreeQUESTl->n_leftbuildtreeCOLONlllr ) );
ragge
1.41
389                                 nfree(l);
ragge
1.1
390                                 break;
391
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.50
399                 case RS:
ragge
1.1
400                 case ASG LS:
401                 case ASG RS:
ragge
1.50
402                         if(tsize(p->n_right->n_typep->n_right->n_dfp->n_right->n_sue) > SZINT)
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.50
486         if (p->n_op == CAST && p->n_type == VOID &&
ragge
1.22
487             p->n_right->n_op == ICON)
ragge
1.50
488                 p->n_right->n_type = VOID;
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.49
708         int dsc;
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.49
737         if (dsc & FIELD) {  /* make fields look like ints */
738                 off = (off/ALINT)*ALINT;
ragge
1.26
739                 sue = MKSUE(INT);
ragge
1.10
740         }
741         if (off != 0)
ragge
1.26
742                 p = clocal(block(PLUSpoffcon(offtdsue), tdsue));
ragge
1.1
743
ragge
1.10
744         p = buildtree(UNARY MULpNIL);
ragge
1.1
745
746         /* if field, build field info */
747
ragge
1.10
748         if (dsc & FIELD) {
ragge
1.26
749                 p = block(FLDpNILq->stype0q->ssue);
ragge
1.49
750                 p->n_rval = PKFIELD(dsc&FLDSIZq->soffset%ALINT);
ragge
1.10
751         }
ragge
1.1
752
ragge
1.19
753         p = clocal(p);
754         return p;
ragge
1.10
755 }
ragge
1.1
756
ragge
1.2
757 int
ragge
1.1
758 notlval(pregister NODE *p; {
759
760         /* return 0 if p an lvalue, 1 otherwise */
761
762         again:
763
ragge
1.22
764         switchp->n_op ){
ragge
1.1
765
766         case FLD:
ragge
1.22
767                 p = p->n_left;
ragge
1.1
768                 goto again;
769
770         case NAME:
771         case OREG:
ragge
1.49
772         case UNARY MUL:
ragge
1.22
773                 ifISARY(p->n_type) || ISFTN(p->n_type) ) return(1);
ragge
1.1
774         case REG:
775                 return(0);
776
777         default:
778                 return(1);
779
780                 }
781
782         }
ragge
1.23
783 /* make a constant node with value i */
ragge
1.1
784 NODE *
ragge
1.23
785 bcon(int i)
786 {
ragge
1.1
787         register NODE *p;
788
ragge
1.26
789         p = block(ICONNILNILINT0MKSUE(INT));
ragge
1.22
790         p->n_lval = i;
ragge
1.23
791         p->n_sp = NULL;
792         return(clocal(p));
793 }
ragge
1.1
794
795 NODE *
ragge
1.10
796 bpsize(NODE *p)
797 {
ragge
1.29
798         return(offcon(psize(p), p->n_typep->n_dfp->n_sue));
ragge
1.10
799 }
ragge
1.1
800
ragge
1.10
801 /*
802  * p is a node of type pointer; psize returns the
803  * size of the thing pointed to
804  */
ragge
1.1
805 OFFSZ
ragge
1.10
806 psize(NODE *p)
807 {
808
ragge
1.22
809         if (!ISPTR(p->n_type)) {
ragge
1.10
810                 uerror("pointer required");
811                 return(SZINT);
812         }
ragge
1.1
813         /* note: no pointers to fields */
ragge
1.29
814         return(tsize(DECREF(p->n_type), p->n_dfp->n_sue));
ragge
1.10
815 }
ragge
1.1
816
ragge
1.10
817 /*
818  * convert an operand of p
819  * f is either CVTL or CVTR
820  * operand has type int, and is converted by the size of the other side
821  */
ragge
1.1
822 NODE *
ragge
1.10
823 convert(NODE *pint f)
824 {
825         NODE *q, *r, *s;
ragge
1.1
826
ragge
1.22
827         q = (f == CVTL) ? p->n_left : p->n_right;
ragge
1.1
828
ragge
1.22
829         s = bpsize(f == CVTL ? p->n_right : p->n_left);
ragge
1.26
830         r = block(PMCONVqsINT0MKSUE(INT));
ragge
1.1
831         r = clocal(r);
ragge
1.13
832         /*
833          * Indexing is only allowed with integer arguments, so insert
834          * SCONV here if arg is not an integer.
835          * XXX - complain?
836          */
ragge
1.22
837         if (r->n_type != INT)
ragge
1.26
838                 r = clocal(block(SCONVrNILINT0MKSUE(INT)));
ragge
1.10
839         if (f == CVTL)
ragge
1.22
840                 p->n_left = r;
ragge
1.1
841         else
ragge
1.22
842                 p->n_right = r;
ragge
1.1
843         return(p);
ragge
1.10
844 }
ragge
1.1
845
ragge
1.2
846 void
ragge
1.1
847 econvertp ) register NODE *p; {
848
849         /* change enums to ints, or appropriate types */
850
851         register TWORD ty;
852
ragge
1.22
853         if( (ty=BTYPE(p->n_type)) == ENUMTY || ty == MOETY ) {
ragge
1.26
854                 if (p->n_sue->suesize == SZCHAR)
ragge
1.6
855                         ty = CHAR;
ragge
1.26
856                 else if (p->n_sue->suesize == SZINT)
ragge
1.6
857                         ty = INT;
ragge
1.26
858                 else if (p->n_sue->suesize == SZSHORT)
ragge
1.6
859