Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20100422191739

Diff

Diff from 1.243 to:

Annotations

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

Annotated File View

ragge
1.243
1 /*      $Id: trees.c,v 1.243 2010/04/22 19:17:39 ragge Exp $    */
ragge
1.51
2 /*
3  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 /*
30  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
31  *
32  * Redistribution and use in source and binary forms, with or without
33  * modification, are permitted provided that the following conditions
34  * are met:
35  *
36  * Redistributions of source code and documentation must retain the above
37  * copyright notice, this list of conditions and the following disclaimer.
38  * Redistributions in binary form must reproduce the above copyright
39  * notice, this list of conditionsand the following disclaimer in the
40  * documentation and/or other materials provided with the distribution.
41  * All advertising materials mentioning features or use of this software
42  * must display the following acknowledgement:
43  *      This product includes software developed or owned by Caldera
44  *      International, Inc.
45  * Neither the name of Caldera International, Inc. nor the names of other
46  * contributors may be used to endorse or promote products derived from
47  * this software without specific prior written permission.
48  *
49  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
50  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
51  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
52  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
53  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
54  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
56  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
58  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
59  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
60  * POSSIBILITY OF SUCH DAMAGE.
61  */
62 /*
63  * Some of the changes from 32V include:
64  * - Understand "void" as type.
65  * - Handle enums as ints everywhere.
ragge
1.57
66  * - Convert some C-specific ops into branches.
ragge
1.51
67  */
68
ragge
1.1
69 # include "pass1.h"
ragge
1.51
70 # include "pass2.h"
ragge
1.1
71
ragge
1.16
72 # include <stdarg.h>
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
ragge
1.242
152 #elif SZPOINT(CHAR) <= SZLONGLONG
153 #define INTPTR  LONGLONG
ragge
1.237
154 #else
155 #error int size unknown
156 #endif
ragge
1.30
157
ragge
1.1
158 NODE *
ragge
1.2
159 buildtree(int oNODE *lNODE *r)
160 {
161         NODE *p, *q;
162         int actions;
163         int opty;
ragge
1.119
164         struct symtab *sp = NULL/* XXX gcc */
ragge
1.2
165         NODE *lr, *ll;
ragge
1.1
166
ragge
1.68
167 #ifdef PCC_DEBUG
ragge
1.128
168         if (bdebug) {
ragge
1.58
169                 printf("buildtree(%s, %p, %p)\n"copst(o), lr);
ragge
1.128
170                 if (lfwalk(leprint0);
171                 if (rfwalk(reprint0);
172         }
ragge
1.68
173 #endif
ragge
1.58
174         opty = coptype(o);
ragge
1.1
175
176         /* check for constants */
177
ragge
1.22
178         ifopty == UTYPE && l->n_op == ICON ){
ragge
1.1
179
180                 switcho ){
181
182                 case NOT:
ragge
1.94
183                 case UMINUS:
ragge
1.1
184                 case COMPL:
185                         ifconvallol ) ) return(l);
186                         break;
187                 }
ragge
1.71
188         } else if (o == NOT && l->n_op == FCON) {
189                 l = clocal(block(SCONVlNILINT0MKSUE(INT)));
ragge
1.94
190         } else ifo == UMINUS && l->n_op == FCON ){
ragge
1.206
191                         l->n_dcon = FLOAT_NEG(l->n_dcon);
ragge
1.1
192                         return(l);
193
ragge
1.44
194         } else ifo==QUEST && l->n_op==ICON ) {
ragge
1.41
195                 CONSZ c = l->n_lval;
196                 nfree(l);
197                 if (c) {
ragge
1.215
198                         walkf(r->n_rightputjops0);
ragge
1.41
199                         tfree(r->n_right);
200                         l = r->n_left;
201                 } else {
ragge
1.215
202                         walkf(r->n_leftputjops0);
ragge
1.41
203                         tfree(r->n_left);
204                         l = r->n_right;
ragge
1.1
205                 }
ragge
1.214
206                 nfree(r);
207                 return(l);
ragge
1.155
208         } else ifopty == BITYPE && l->n_op == ICON && r->n_op == ICON ){
ragge
1.1
209
210                 switcho ){
211
ragge
1.159
212                 case PLUS:
213                 case MINUS:
214                 case MUL:
215                 case DIV:
216                 case MOD:
217                         /*
218                          * Do type propagation for simple types here.
219                          * The constant value is correct anyway.
220                          * Maybe this op shortcut should be removed?
221                          */
222                         if (l->n_sp == NULL && r->n_sp == NULL &&
223                             l->n_type < BTMASK && r->n_type < BTMASK) {
224                                 if (l->n_type > r->n_type)
225                                         r->n_type = l->n_type;
226                                 else
227                                         l->n_type = r->n_type;
228                         }
229                         /* FALLTHROUGH */
ragge
1.1
230                 case ULT:
231                 case UGT:
232                 case ULE:
233                 case UGE:
234                 case LT:
235                 case GT:
236                 case LE:
237                 case GE:
238                 case EQ:
ragge
1.48
239                 case NE:
ragge
1.1
240                 case ANDAND:
241                 case OROR:
242                 case AND:
243                 case OR:
244                 case ER:
245                 case LS:
246                 case RS:
ragge
1.200
247                         if (!ISPTR(l->n_type) && !ISPTR(r->n_type)) {
248                                 ifconvallor ) ) {
249                                         nfree(r);
250                                         return(l);
251                                 }
ragge
1.44
252                         }
ragge
1.1
253                         break;
254                 }
ragge
1.44
255         } else if (opty == BITYPE && (l->n_op == FCON || l->n_op == ICON) &&
256             (r->n_op == FCON || r->n_op == ICON) && (o == PLUS || o == MINUS ||
gmcgarry
1.234
257             o == MUL || o == DIV || (o >= EQ && o <= GT) )) {
258                 if (l->n_op == ICON)
259                         l->n_dcon = FLOAT_CAST(l->n_lvall->n_type);
260                 if (r->n_op == ICON)
261                         r->n_dcon = FLOAT_CAST(r->n_lvalr->n_type);
ragge
1.44
262                 switch(o){
263                 case PLUS:
264                 case MINUS:
265                 case MUL:
266                 case DIV:
267                         switch (o) {
268                         case PLUS:
ragge
1.206
269                                 l->n_dcon = FLOAT_PLUS(l->n_dconr->n_dcon);
270                                 break;
ragge
1.44
271                         case MINUS:
ragge
1.206
272                                 l->n_dcon = FLOAT_MINUS(l->n_dconr->n_dcon);
273                                 break;
ragge
1.44
274                         case MUL:
ragge
1.206
275                                 l->n_dcon = FLOAT_MUL(l->n_dconr->n_dcon);
276                                 break;
ragge
1.44
277                         case DIV:
ragge
1.206
278                                 if (FLOAT_ISZERO(r->n_dcon))
otto
1.170
279                                         goto runtime;
ragge
1.206
280                                 l->n_dcon = FLOAT_DIV(l->n_dconr->n_dcon);
281                                 break;
ragge
1.44
282                         }
283                         l->n_op = FCON;
284                         l->n_type = DOUBLE;
285                         l->n_sue = MKSUE(DOUBLE);
286                         nfree(r);
287                         return(l);
gmcgarry
1.234
288                 case EQ:
289                 case NE:
290                 case LE:
291                 case LT:
292                 case GE:
293                 case GT:
294                         switch (o) {
295                         case EQ:
296                                 l->n_lval = FLOAT_EQ(l->n_dconr->n_dcon);
297                                 break;
298                         case NE:
299                                 l->n_lval = FLOAT_NE(l->n_dconr->n_dcon);
300                                 break;
301                         case LE:
302                                 l->n_lval = FLOAT_LE(l->n_dconr->n_dcon);
303                                 break;
304                         case LT:
305                                 l->n_lval = FLOAT_LT(l->n_dconr->n_dcon);
306                                 break;
307                         case GE:
308                                 l->n_lval = FLOAT_GE(l->n_dconr->n_dcon);
309                                 break;
310                         case GT:
311                                 l->n_lval = FLOAT_GT(l->n_dconr->n_dcon);
312                                 break;
313                         }
314                         nfree(r);
ragge
1.236
315                         r = bcon(l->n_lval);
316                         nfree(l);
317                         return r;
ragge
1.1
318                 }
ragge
1.44
319         }
otto
1.170
320 runtime:
ragge
1.30
321         /* its real; we must make a new node */
ragge
1.1
322
ragge
1.26
323         p = block(olrINT0MKSUE(INT));
ragge
1.1
324
325         actions = opact(p);
326
ragge
1.66
327         if (actions & LVAL) { /* check left descendent */
328                 if (notlval(p->n_left)) {
329                         uerror("lvalue required");
stefan
1.186
330                         nfree(p);
331                         return l;
ragge
1.68
332 #ifdef notyet
ragge
1.67
333                 } else {
334                         if ((l->n_type > BTMASK && ISCON(l->n_qual)) ||
335                             (l->n_type <= BTMASK && ISCON(l->n_qual << TSHIFT)))
336                                 if (blevel > 0)
337                                         uerror("lvalue is declared const");
ragge
1.68
338 #endif
ragge
1.67
339                 }
ragge
1.66
340         }
ragge
1.1
341
342         ifactions & NCVTR ){
ragge
1.22
343                 p->n_left = pconvertp->n_left );
ragge
1.1
344                 }
345         else if( !(actions & NCVT ) ){
346                 switchopty ){
347
348                 case BITYPE:
ragge
1.22
349                         p->n_right = pconvertp->n_right );
ragge
1.1
350                 case UTYPE:
ragge
1.22
351                         p->n_left = pconvertp->n_left );
ragge
1.1
352
353                         }
354                 }
355
ragge
1.64
356         if ((actions&PUN) && (o!=CAST))
ragge
1.1
357                 chkpun(p);
358
359         ifactions & (TYPL|TYPR) ){
360
ragge
1.22
361                 q = (actions&TYPL) ? p->n_left : p->n_right;
ragge
1.1
362
ragge
1.22
363                 p->n_type = q->n_type;
ragge
1.66
364                 p->n_qual = q->n_qual;
ragge
1.29
365                 p->n_df = q->n_df;
ragge
1.26
366                 p->n_sue = q->n_sue;
ragge
1.1
367                 }
368
369         ifactions & CVTL ) p = convertpCVTL );
370         ifactions & CVTR ) p = convertpCVTR );
371         ifactions & TYMATCH ) p = tymatch(p);
372         ifactions & PTMATCH ) p = ptmatch(p);
373
374         ifactions & OTHER ){
ragge
1.226
375                 struct suedef *sue2;
ragge
1.225
376                 struct suedef *sue;
377
ragge
1.22
378                 l = p->n_left;
379                 r = p->n_right;
ragge
1.1
380
381                 switch(o){
382
383                 case NAME:
ragge
1.203
384                         cerror("buildtree NAME");
ragge
1.1
385
386                 case STREF:
387                         /* p->x turned into *(p+offset) */
388                         /* rhs must be a name; check correctness */
389
ragge
1.23
390                         /* Find member symbol struct */
391                         if (l->n_type != PTR+STRTY && l->n_type != PTR+UNIONTY){
392                                 uerror("struct or union required");
393                                 break;
394                         }
395
ragge
1.225
396 #define GETSUE(x, y)    for (x = y; x->suep; x = x->suep)
397
398                         /* find type sue */
399                         GETSUE(suel->n_sue);
400                         if ((sp = sue->suem) == NULL) {
ragge
1.23
401                                 uerror("undefined struct or union");
stefan
1.190
402                                 break;
403                         }
ragge
1.23
404
ragge
1.218
405                         sp = findmember(spr->n_name);
406 #ifdef notdef
ragge
1.23
407                         name = r->n_name;
ragge
1.187
408                         for (; sp != NULLsp = sp->snext) {
ragge
1.23
409                                 if (sp->sname == name)
410                                         break;
411                         }
ragge
1.218
412 #endif
stefan
1.190
413                         if (sp == NULL) {
ragge
1.218
414                                 uerror("member '%s' not declared"r->n_name);
stefan
1.190
415                                 break;
416                         }
ragge
1.23
417
418                         r->n_sp = sp;
419                         p = stref(p);
420                         break;
421
ragge
1.94
422                 case UMUL:
ragge
1.93
423                         if (l->n_op == ADDROF) {
ragge
1.41
424                                 nfree(p);
ragge
1.22
425                                 p = l->n_left;
ragge
1.41
426                                 nfree(l);
427                         }
ragge
1.22
428                         if( !ISPTR(l->n_type))uerror("illegal indirection");
429                         p->n_type = DECREF(l->n_type);
ragge
1.67
430                         p->n_qual = DECREF(l->n_qual);
ragge
1.29
431                         p->n_df = l->n_df;
ragge
1.26
432                         p->n_sue = l->n_sue;
ragge
1.1
433                         break;
434
ragge
1.93
435                 case ADDROF:
ragge
1.22
436                         switchl->n_op ){
ragge
1.1
437
ragge
1.94
438                         case UMUL:
ragge
1.41
439                                 nfree(p);
ragge
1.22
440                                 p = l->n_left;
ragge
1.41
441                                 nfree(l);
ragge
1.130
442                         case TEMP:
ragge
1.1
443                         case NAME:
ragge
1.68
444                                 p->n_type = INCREF(l->n_type);
445                                 p->n_qual = INCQAL(l->n_qual);
ragge
1.29
446                                 p->n_df = l->n_df;
ragge
1.26
447                                 p->n_sue = l->n_sue;
ragge
1.1
448                                 break;
449
450                         case COMOP:
ragge
1.41
451                                 nfree(p);
ragge
1.93
452                                 lr = buildtree(ADDROFl->n_rightNIL);
ragge
1.22
453                                 p = buildtreeCOMOPl->n_leftlr );
ragge
1.41
454                                 nfree(l);
ragge
1.1
455                                 break;
456
457                         case QUEST:
ragge
1.93
458                                 lr = buildtreeADDROFl->n_right->n_rightNIL );
459                                 ll = buildtreeADDROFl->n_right->n_leftNIL );
ragge
1.41
460                                 nfree(p); nfree(l->n_right);
ragge
1.22
461                                 p = buildtreeQUESTl->n_leftbuildtreeCOLONlllr ) );
ragge
1.41
462                                 nfree(l);
ragge
1.1
463                                 break;
464
465                         default:
ragge
1.22
466                                 uerror("unacceptable operand of &: %d"l->n_op );
ragge
1.1
467                                 break;
468                                 }
469                         break;
470
471                 case LS:
ragge
1.150
472                 case RS/* must make type size at least int... */
473                         if (p->n_type == CHAR || p->n_type == SHORT) {
474                                 p->n_left = makety(lINT00MKSUE(INT));
475                         } else if (p->n_type == UCHAR || p->n_type == USHORT) {
476                                 p->n_left = makety(lUNSIGNED00,
477                                     MKSUE(UNSIGNED));
478                         }
479                         l = p->n_left;
480                         p->n_type = l->n_type;
481                         p->n_qual = l->n_qual;
482                         p->n_df = l->n_df;
483                         p->n_sue = l->n_sue;
484
485                         /* FALLTHROUGH */
ragge
1.95
486                 case LSEQ:
ragge
1.150
487                 case RSEQ/* ...but not for assigned types */
488                         if(tsize(r->n_typer->n_dfr->n_sue) > SZINT)
489                                 p->n_right = makety(rINT00MKSUE(INT));
ragge
1.1
490                         break;
491
492                 case RETURN:
493                 case ASSIGN:
494                 case CAST:
495                         /* structure assignment */
496                         /* take the addresses of the two sides; then make an
ragge
1.2
497                          * operator using STASG and
498                          * the addresses of left and right */
ragge
1.1
499
500                         {
ragge
1.2
501                                 TWORD t;
ragge
1.29
502                                 union dimfun *d;
ragge
1.1
503
ragge
1.225
504                                 GETSUE(suel->n_sue);
505                                 GETSUE(sue2r->n_sue);
506                                 if (sue->suem != sue2->suem)
ragge
1.26
507                                         uerror("assignment of different structures");
ragge
1.1
508
ragge
1.93
509                                 r = buildtree(ADDROFrNIL);
ragge
1.22
510                                 t = r->n_type;
ragge
1.29
511                                 d = r->n_df;
ragge
1.26
512                                 sue = r->n_sue;
ragge
1.1
513
ragge
1.28
514                                 l = block(STASGlrtdsue);
gmcgarry
1.177
515                                 l = clocal(l);
ragge
1.1
516
517                                 ifo == RETURN ){
ragge
1.41
518                                         nfree(p);
ragge
1.1
519                                         p = l;
520                                         break;
ragge
1.28
521                                 }
ragge
1.1
522
ragge
1.94
523                                 p->n_op = UMUL;
ragge
1.22
524                                 p->n_left = l;
525                                 p->n_right = NIL;
ragge
1.1
526                                 break;
527                                 }
528                 case COLON:
529                         /* structure colon */
530
ragge
1.226
531                         GETSUE(suel->n_sue);
532                         GETSUE(sue2r->n_sue);
533                         if (sue->suem != sue2->suem)
ragge
1.26
534                                 uerror"type clash in conditional" );
ragge
1.1
535                         break;
536
537                 case CALL:
ragge
1.45
538                         p->n_right = r = strargs(p->n_right);
ragge
1.171
539                         p = funcode(p);
540                         /* FALLTHROUGH */
ragge
1.95
541                 case UCALL:
ragge
1.23
542                         if (!ISPTR(l->n_type))
543                                 uerror("illegal function");
ragge
1.22
544                         p->n_type = DECREF(l->n_type);
ragge
1.23
545                         if (!ISFTN(p->n_type))
546                                 uerror("illegal function");
547                         p->n_type = DECREF(p->n_type);
ragge
1.29
548                         p->n_df = l->n_df;
ragge
1.26
549                         p->n_sue = l->n_sue;
ragge
1.93
550                         if (l->n_op == ADDROF && l->n_left->n_op == NAME &&
ragge
1.23
551                             l->n_left->n_sp != NULL && l->n_left->n_sp != NULL &&
552                             (l->n_left->n_sp->sclass == FORTRAN ||
553                             l->n_left->n_sp->sclass == UFORTRAN)) {
ragge
1.22
554                                 p->n_op += (FORTCALL-CALL);
ragge
1.23
555                         }
556                         if (p->n_type == STRTY || p->n_type == UNIONTY) {
ragge
1.1
557                                 /* function returning structure */
558                                 /*  make function really return ptr to str., with * */
559
ragge
1.22
560                                 p->n_op += STCALL-CALL;
ragge
1.23
561                                 p->n_type = INCREF(p->n_type);
ragge
1.149
562                                 p = clocal(p); /* before recursing */
ragge
1.94
563                                 p = buildtree(UMULpNIL);
ragge
1.1
564
565                                 }
566                         break;
567
568                 default:
569                         cerror"other code %d"o );
570                         }
571
572                 }
573
ragge
1.11
574         /*
575          * Allow (void)0 casts.
576          * XXX - anything on the right side must be possible to cast.
577          * XXX - remove void types further on.
578          */
ragge
1.50
579         if (p->n_op == CAST && p->n_type == VOID &&
ragge
1.22
580             p->n_right->n_op == ICON)
ragge
1.50
581                 p->n_right->n_type = VOID;
ragge
1.11
582
ragge
1.68
583         if (actions & CVTO)
584                 p = oconvert(p);
ragge
1.1
585         p = clocal(p);
586
ragge
1.30
587 #ifdef PCC_DEBUG
ragge
1.74
588         if (bdebug) {
589                 printf("End of buildtree:\n");
ragge
1.68
590                 fwalk(peprint0);
ragge
1.74
591         }
ragge
1.30
592 #endif
ragge
1.1
593
594         return(p);
595
596         }
597
ragge
1.218
598 /* Find a member in a struct or union.  May be an unnamed member */
599 static struct symtab *
600 findmember(struct symtab *spchar *s)
601 {
602         struct symtab *sp2, *sp3;
603
604         for (; sp != NULLsp = sp->snext) {
605                 if (sp->sname[0] == '*') {
606                         /* unnamed member, recurse down */
ragge
1.225
607                         if ((sp2 = findmember(sp->ssue->suems))) {
ragge
1.218
608                                 sp3 = tmpalloc(sizeof (struct symtab));
609                                 *sp3 = *sp2;
610                                 sp3->soffset += sp->soffset;
611                                 return sp3;
612                         }
613                 } else if (sp->sname == s)
614                         return sp;
615         }
616         return NULL;
617 }
618
619
ragge
1.107
620 /*
ragge
1.214
621  * Check if there will be a lost label destination inside of a ?:
622  * It cannot be reached so just print it out.
623  */
624 static void
ragge
1.215
625 putjops(NODE *pvoid *arg)
ragge
1.214
626 {
627         if (p->n_op == COMOP && p->n_left->n_op == GOTO)
628                 plabel(p->n_left->n_left->n_lval+1);
629 }
630
631 /*
ragge
1.199
632  * Build a name node based on a symtab entry.
633  * broken out from buildtree().
634  */
635 NODE *
636 nametree(struct symtab *sp)
637 {
638         NODE *p;
639
640         p = block(NAMENILNILsp->stypesp->sdfsp->ssue);
641         p->n_qual = sp->squal;
642         p->n_sp = sp;
643
644 #ifndef NO_C_BUILTINS
645         if (sp->sname[0] == '_' && strncmp(sp->sname"__builtin_"10) == 0)
646                 return p;  /* do not touch builtins here */
647         
648 #endif
649
650         if (sp->sflags & STNODE) {
651                 /* Generated for optimizer */
652                 p->n_op = TEMP;
653                 p->n_rval = sp->soffset;
654         }
655
656 #ifdef GCC_COMPAT
657         /* Get a label name */
658         if (sp->sflags == SLBLNAME) {
659                 p->n_type = VOID;
660                 p->n_sue = MKSUE(VOID);
661         }
662 #endif
663         if (sp->stype == UNDEF) {
664                 uerror("%s undefined"sp->sname);
665                 /* make p look reasonable */
666                 p->n_type = INT;
667                 p->n_sue = MKSUE(INT);
668                 p->n_df = NULL;
669                 defid(pSNULL);
670         }
671         if (sp->sclass == MOE) {
672                 p->n_op = ICON;
673                 p->n_lval = sp->soffset;
674                 p->n_df = NULL;
675                 p->n_sp = NULL;
676         }
677         return clocal(p);
678 }
679
680 /*
ragge
1.241
681  * Cast a node to another type by inserting a cast.
ragge
1.240
682  * Just a nicer interface to buildtree.
683  * Returns the new tree.
684  */
685 NODE *
686 cast(NODE *pTWORD tTWORD u)
687 {
688         NODE *q;
689
690         q = block(NAMENILNILt0MKSUE(BTYPE(t)));
691         q->n_qual = u;
692         q = buildtree(CASTqp);
693         p = q->n_right;
694         nfree(q->n_left);
695         nfree(q);
696         return p;
697 }
698
699 /*
ragge
1.241
700  * Cast and complain if necessary by not inserining a cast.
701  */
702 NODE *
703 ccast(NODE *pTWORD tTWORD uunion dimfun *dfstruct suedef *sue)
704 {
705         NODE *q;
706
707         /* let buildtree do typechecking (and casting) */ 
708         q = block(NAMENILNILtdfsue);
709         p = buildtree(ASSIGNqp);
710         nfree(p->n_left);
711         q = optim(p->n_right);
712         nfree(p);
713         return q;
714 }
715
716 /*
ragge
1.107
717  * Do a conditional branch.
718  */
719 void
720 cbranch(NODE *pNODE *q)
721 {
722         p = buildtree(CBRANCHpq);
723         if (p->n_left->n_op == ICON) {
ragge
1.208
724                 if (p->n_left->n_lval != 0) {
ragge
1.107
725                         branch(q->n_lval); /* branch always */
ragge
1.208
726                         reached = 0;
727                 }
ragge
1.107
728                 tfree(p);
729                 tfree(q);
730                 return;
731         }
732         ecomp(p);
733 }
734
ragge
1.1
735 NODE *
ragge
1.45
736 strargsp ) register NODE *p;  { /* rewrite structure flavored arguments */
ragge
1.1
737
ragge
1.45
738         ifp->n_op == CM ){
739                 p->n_left = strargsp->n_left );
740                 p->n_right = strargsp->n_right );
ragge
1.1
741                 returnp );
742                 }
743
ragge
1.22
744         ifp->n_type == STRTY || p->n_type == UNIONTY ){
ragge
1.29
745                 p = block(STARGpNILp->n_typep->n_dfp->n_sue);
ragge
1.93
746                 p->n_left = buildtreeADDROFp->n_leftNIL );
ragge
1.1
747                 p = clocal(p);
748                 }
749         returnp );
ragge
1.2
750 }
ragge
1.1
751
ragge
1.2
752 /*
753  * apply the op o to the lval part of p; if binary, rhs is val
754  */
755 int
756 conval(NODE *pint oNODE *q)
757 {
ragge
1.1
758         int iu;
759         CONSZ val;
ragge
1.159
760         U_CONSZ v1v2;
ragge
1.1
761
ragge
1.22
762         val = q->n_lval;
763         u = ISUNSIGNED(p->n_type) || ISUNSIGNED(q->n_type);
ragge
1.1
764         ifu && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE);
765
ragge
1.23
766         if (p->n_sp != NULL && q->n_sp != NULL)
767                 return(0);
768         if (q->n_sp != NULL && o != PLUS)
769                 return(0);
770         if (p->n_sp != NULL && o != PLUS && o != MINUS)
771                 return(0);
ragge
1.161
772         v1 = p->n_lval;
773         v2 = q->n_lval;
ragge
1.1
774         switcho ){
775
776         case PLUS:
ragge
1.22
777                 p->n_lval += val;
ragge
1.23
778                 if (p->n_sp == NULL) {
ragge
1.237
779                         p->n_right = q->n_right;
ragge
1.22
780                         p->n_type = q->n_type;
ragge
1.23
781                 }
ragge
1.1
782                 break;
783         case MINUS:
ragge
1.22
784                 p->n_lval -= val;
ragge
1.1
785                 break;
786         case MUL:
ragge
1.22
787                 p->n_lval *= val;
ragge
1.1
788                 break;
789         case DIV:
ragge
1.46
790                 if (val == 0)
791                         uerror("division by 0");
ragge
1.159
792                 else  {
793                         if (u) {
794                                 v1 /= v2;
795                                 p->n_lval = v1;
796                         } else
797                                 p->n_lval /= val;
798                 }
ragge
1.1
799                 break;
800         case MOD:
ragge
1.46
801                 if (val == 0)
802                         uerror("division by 0");
ragge
1.159
803                 else  {
804                         if (u) {
805                                 v1 %= v2;
806                                 p->n_lval = v1;
807                         } else
808                                 p->n_lval %= val;
809                 }
ragge
1.1
810                 break;
811         case AND:
ragge
1.22
812                 p->n_lval &= val;
ragge
1.1
813                 break;
814         case OR:
ragge
1.22
815                 p->n_lval |= val;
ragge
1.1
816                 break;
817         case ER:
ragge
1.22
818                 p->n_lval ^= val;
ragge
1.1
819                 break;
820         case LS:
gmcgarry
1.238
821                 i = (int)val;
ragge
1.22
822                 p->n_lval = p->n_lval << i;
ragge
1.1
823                 break;
824         case RS:
gmcgarry
1.238
825                 i = (int)val;
ragge
1.159
826                 if (u) {
827                         v1 = v1 >> i;
828                         p->n_lval = v1;
829                 } else
830                         p->n_lval = p->n_lval >> i;
ragge
1.1
831                 break;
832
ragge
1.94
833         case UMINUS:
ragge
1.22
834                 p->n_lval = - p->n_lval;
ragge
1.1
835                 break;
836         case COMPL:
ragge
1.22
837                 p->n_lval = ~p->n_lval;
ragge
1.1
838                 break;
839         case NOT:
ragge
1.22
840                 p->n_lval = !p->n_lval;
ragge
1.1
841                 break;
842         case LT:
ragge
1.22
843                 p->n_lval = p->n_lval < val;
ragge
1.1
844                 break;
845         case LE:
ragge
1.22
846                 p->n_lval = p->n_lval <= val;
ragge
1.1
847                 break;
848         case GT:
ragge
1.22
849                 p->n_lval = p->n_lval > val;
ragge
1.1
850                 break;
851         case GE:
ragge
1.22
852                 p->n_lval = p->n_lval >= val;
ragge
1.1
853                 break;
854         case ULT:
ragge
1.159
855                 p->n_lval = v1 < v2;
ragge
1.1
856                 break;
857         case ULE:
ragge
1.159
858                 p->n_lval = v1 <= v2;
ragge
1.1
859                 break;
860         case UGT:
ragge
1.159
861                 p->n_lval = v1 > v2;
ragge
1.1
862                 break;
863         case UGE:
ragge
1.159
864                 p->n_lval = v1 >= v2;
ragge
1.1
865                 break;
866         case EQ:
ragge
1.22
867                 p->n_lval = p->n_lval == val;
ragge
1.1
868                 break;
869         case NE:
ragge
1.22
870                 p->n_lval = p->n_lval != val;
ragge
1.1
871                 break;
ragge
1.155
872         case ANDAND:
873                 p->n_lval = p->n_lval && val;
874                 break;
ragge
1.154
875         case OROR:
876                 p->n_lval = p->n_lval || val;
877                 break;
ragge
1.1
878         default:
879                 return(0);
880                 }
881         return(1);
882         }
883
ragge
1.7
884 /*
885  * Checks p for the existance of a pun.  This is called when the op of p
886  * is ASSIGN, RETURN, CAST, COLON, or relational.
887  * One case is when enumerations are used: this applies only to lint.
888  * In the other case, one operand is a pointer, the other integer type
889  * we check that this integer is in fact a constant zero...
890  * in the case of ASSIGN, any assignment of pointer to integer is illegal
891  * this falls out, because the LHS is never 0.
ragge
1.212
892  * XXX - check for COMOPs in assignment RHS?
ragge
1.7
893  */
ragge
1.2
894 void
ragge
1.7
895 chkpun(NODE *p)
896