Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20090519192555

Diff

Diff from 1.235 to:

Annotations

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

Annotated File View

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