Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030730141155

Diff

Diff from 1.63 to:

Annotations

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

Annotated File View

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