Quick Search:

View

Revision:
Expand:  
Changeset: r-1-0-0:ragge:20110301173928

Diff

Diff from 1.272.2.1 to:

Annotations

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

Annotated File View

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