Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20070722125056

Diff

Diff from 1.158 to:

Annotations

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

Annotated File View

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