Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20100602103433

Diff

Diff from 1.247 to:

Annotations

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

Annotated File View

ragge
1.247
1 /*      $Id: trees.c,v 1.247 2010/06/02 10:34:33 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                         /* 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.241
679  * Cast a node to another type by inserting a cast.
ragge
1.240
680  * Just a nicer interface to buildtree.
681  * Returns the new tree.
682  */
683 NODE *
684 cast(NODE *pTWORD tTWORD u)
685 {
686         NODE *q;
687
688         q = block(NAMENILNILt0MKSUE(BTYPE(t)));
689         q->n_qual = u;
690         q = buildtree(CASTqp);
691         p = q->n_right;
692         nfree(q->n_left);
693         nfree(q);
694         return p;
695 }
696
697 /*
ragge
1.241
698  * Cast and complain if necessary by not inserining a cast.
699  */
700 NODE *
701 ccast(NODE *pTWORD tTWORD uunion dimfun *dfstruct suedef *sue)
702 {
703         NODE *q;
704
705         /* let buildtree do typechecking (and casting) */ 
706         q = block(NAMENILNILtdfsue);
707         p = buildtree(ASSIGNqp);
708         nfree(p->n_left);
709         q = optim(p->n_right);
710         nfree(p);
711         return q;
712 }
713
714 /*
ragge
1.107
715  * Do a conditional branch.
716  */
717 void
718 cbranch(NODE *pNODE *q)
719 {
720         p = buildtree(CBRANCHpq);
721         if (p->n_left->n_op == ICON) {
ragge
1.208
722                 if (p->n_left->n_lval != 0) {
ragge
1.107
723                         branch(q->n_lval); /* branch always */
ragge
1.208
724                         reached = 0;
725                 }
ragge
1.107
726                 tfree(p);
727                 tfree(q);
728                 return;
729         }
730         ecomp(p);
731 }
732
ragge
1.1
733 NODE *
ragge
1.45
734 strargsp ) register NODE *p;  { /* rewrite structure flavored arguments */
ragge
1.1
735
ragge
1.45
736         ifp->n_op == CM ){
737                 p->n_left = strargsp->n_left );
738                 p->n_right = strargsp->n_right );
ragge
1.1
739                 returnp );
740                 }
741
ragge
1.22
742         ifp->n_type == STRTY || p->n_type == UNIONTY ){
ragge
1.29
743                 p = block(STARGpNILp->n_typep->n_dfp->n_sue);
ragge
1.93
744                 p->n_left = buildtreeADDROFp->n_leftNIL );
ragge
1.1
745                 p = clocal(p);
746                 }
747         returnp );
ragge
1.2
748 }
ragge
1.1
749
ragge
1.2
750 /*
751  * apply the op o to the lval part of p; if binary, rhs is val
752  */
753 int
754 conval(NODE *pint oNODE *q)
755 {
ragge
1.1
756         int iu;
757         CONSZ val;
ragge
1.159
758         U_CONSZ v1v2;
ragge
1.1
759
ragge
1.22
760         val = q->n_lval;
761         u = ISUNSIGNED(p->n_type) || ISUNSIGNED(q->n_type);
ragge
1.1
762         ifu && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE);
763
ragge
1.23
764         if (p->n_sp != NULL && q->n_sp != NULL)
765                 return(0);
766         if (q->n_sp != NULL && o != PLUS)
767                 return(0);
768         if (p->n_sp != NULL && o != PLUS && o != MINUS)
769                 return(0);
ragge
1.161
770         v1 = p->n_lval;
771         v2 = q->n_lval;
ragge
1.1
772         switcho ){
773
774         case PLUS:
ragge
1.22
775                 p->n_lval += val;
ragge
1.23
776                 if (p->n_sp == NULL) {
ragge
1.237
777                         p->n_right = q->n_right;
ragge
1.22
778                         p->n_type = q->n_type;
ragge
1.23
779                 }
ragge
1.1
780                 break;
781         case MINUS:
ragge
1.22
782                 p->n_lval -= val;
ragge
1.1
783                 break;
784         case MUL:
ragge
1.22
785                 p->n_lval *= val;
ragge
1.1
786                 break;
787         case DIV:
ragge
1.46
788                 if (val == 0)
789                         uerror("division by 0");
ragge
1.159
790                 else  {
791                         if (u) {
792                                 v1 /= v2;
793                                 p->n_lval = v1;
794                         } else
795                                 p->n_lval /= val;
796                 }
ragge
1.1
797                 break;
798         case MOD:
ragge
1.46
799                 if (val == 0)
800                         uerror("division by 0");
ragge
1.159
801                 else  {
802                         if (u) {
803                                 v1 %= v2;
804                                 p->n_lval = v1;
805                         } else
806                                 p->n_lval %= val;
807                 }
ragge
1.1
808                 break;
809         case AND:
ragge
1.22
810                 p->n_lval &= val;
ragge
1.1
811                 break;
812         case OR:
ragge
1.22
813                 p->n_lval |= val;
ragge
1.1
814                 break;
815         case ER:
ragge
1.22
816                 p->n_lval ^= val;
ragge
1.1
817                 break;
818         case LS:
gmcgarry
1.238
819                 i = (int)val;
ragge
1.22
820                 p->n_lval = p->n_lval << i;
ragge
1.1
821                 break;
822         case RS:
gmcgarry
1.238
823                 i = (int)val;
ragge
1.159
824                 if (u) {
825                         v1 = v1 >> i;
826                         p->n_lval = v1;
827                 } else
828                         p->n_lval = p->n_lval >> i;
ragge
1.1
829                 break;
830
ragge
1.94
831         case UMINUS:
ragge
1.22
832                 p->n_lval = - p->n_lval;
ragge
1.1
833                 break;
834         case COMPL:
ragge
1.22
835                 p->n_lval = ~p->n_lval;
ragge
1.1
836                 break;
837         case NOT:
ragge
1.22
838                 p->n_lval = !p->n_lval;
ragge
1.1
839                 break;
840         case LT:
ragge
1.22
841                 p->n_lval = p->n_lval < val;
ragge
1.1
842                 break;
843         case LE:
ragge
1.22
844                 p->n_lval = p->n_lval <= val;
ragge
1.1
845                 break;
846         case GT:
ragge
1.22
847                 p->n_lval = p->n_lval > val;
ragge
1.1
848                 break;
849         case GE:
ragge
1.22
850                 p->n_lval = p->n_lval >= val;
ragge
1.1
851                 break;
852         case ULT:
ragge
1.159
853                 p->n_lval = v1 < v2;
ragge
1.1
854                 break;
855         case ULE:
ragge
1.159
856                 p->n_lval = v1 <= v2;
ragge
1.1
857                 break;
858         case UGT:
ragge
1.159
859                 p->n_lval = v1 > v2;
ragge
1.1
860                 break;
861         case UGE:
ragge
1.159
862                 p->n_lval = v1 >= v2;
ragge
1.1
863                 break;
864         case EQ:
ragge
1.22
865                 p->n_lval = p->n_lval == val;
ragge
1.1
866                 break;
867         case NE:
ragge
1.22
868                 p->n_lval = p->n_lval != val;
ragge
1.1
869                 break;
ragge
1.155
870         case ANDAND:
871                 p->n_lval = p->n_lval && val;
872                 break;
ragge
1.154
873         case OROR:
874                 p->n_lval = p->n_lval || val;
875                 break;
ragge
1.1
876         default:
877                 return(0);
878                 }
879         return(1);
880         }
881
ragge
1.7
882 /*
883  * Checks p for the existance of a pun.  This is called when the op of p
884  * is ASSIGN, RETURN, CAST, COLON, or relational.
885  * One case is when enumerations are used: this applies only to lint.
886  * In the other case, one operand is a pointer, the other integer type
887  * we check that this integer is in fact a constant zero...
888  * in the case of ASSIGN, any assignment of pointer to integer is illegal
889  * this falls out, because the LHS is never 0.
ragge
1.212
890  * XXX - check for COMOPs in assignment RHS?
ragge
1.7
891  */
ragge
1.2
892 void
ragge
1.7
893 chkpun(NODE *p)
894 {
ragge
1.29
895