Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20081115140239

Diff

Diff from 1.214 to:

Annotations

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

Annotated File View

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