Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030822145342

Diff

Diff from 1.82 to:

Annotations

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

Annotated File View

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