Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20090526172118

Diff

Diff from 1.237 to:

Annotations

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

Annotated File View

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