Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:gmcgarry:20090813080125

Diff

Diff from 1.238 to:

Annotations

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

Annotated File View

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