Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030803150037

Diff

Diff from 1.70 to:

Annotations

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

Annotated File View

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