Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20080106150706

Diff

Diff from 1.184 to:

Annotations

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

Annotated File View

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