Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20110531152625

Diff

Diff from 1.282 to:

Annotations

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

Annotated File View

ragge
1.282
1 /*      $Id: trees.c,v 1.282 2011/05/31 15:26:25 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
ragge
1.275
130 # define PROML 020000   /* promote left operand */
ragge
1.1
131
132 /* node conventions:
133
134         NAME:   rval>0 is stab index for external
135                 rval<0 is -inlabel number
136                 lval is offset in bits
137         ICON:   lval has the value
138                 rval has the STAB index, or - label number,
139                         if a name whose address is in the constant
140                 rval = NONAME means no name
141         REG:    rval is reg. identification cookie
142
143         */
144
ragge
1.30
145 int bdebug = 0;
ragge
1.208
146 extern int negrel[];
147
ragge
1.1
148 NODE *
ragge
1.2
149 buildtree(int oNODE *lNODE *r)
150 {
151         NODE *p, *q;
152         int actions;
153         int opty;
ragge
1.119
154         struct symtab *sp = NULL/* XXX gcc */
ragge
1.2
155         NODE *lr, *ll;
ragge
1.1
156
ragge
1.68
157 #ifdef PCC_DEBUG
ragge
1.128
158         if (bdebug) {
ragge
1.58
159                 printf("buildtree(%s, %p, %p)\n"copst(o), lr);
ragge
1.128
160                 if (lfwalk(leprint0);
161                 if (rfwalk(reprint0);
162         }
ragge
1.68
163 #endif
ragge
1.58
164         opty = coptype(o);
ragge
1.1
165
166         /* check for constants */
167
ragge
1.271
168         if (o == ANDAND || o == OROR || o == NOT) {
169                 if (l->n_op == FCON) {
170                         p = bcon(!FLOAT_ISZERO(l->n_dcon));
171                         nfree(l);
172                         l = p;
173                 }
174                 if (o != NOT && r->n_op == FCON) {
175                         p = bcon(!FLOAT_ISZERO(r->n_dcon));
176                         nfree(r);
177                         r = p;
178                 }
179         }
180
ragge
1.22
181         ifopty == UTYPE && l->n_op == ICON ){
ragge
1.1
182
183                 switcho ){
184
185                 case NOT:
ragge
1.94
186                 case UMINUS:
ragge
1.1
187                 case COMPL:
188                         ifconvallol ) ) return(l);
189                         break;
190                 }
ragge
1.71
191         } else if (o == NOT && l->n_op == FCON) {
ragge
1.274
192                 l = clocal(block(SCONVlNILINT00));
ragge
1.94
193         } else ifo == UMINUS && l->n_op == FCON ){
ragge
1.206
194                         l->n_dcon = FLOAT_NEG(l->n_dcon);
ragge
1.1
195                         return(l);
196
ragge
1.44
197         } else ifo==QUEST && l->n_op==ICON ) {
ragge
1.41
198                 CONSZ c = l->n_lval;
199                 nfree(l);
200                 if (c) {
ragge
1.215
201                         walkf(r->n_rightputjops0);
ragge
1.41
202                         tfree(r->n_right);
203                         l = r->n_left;
204                 } else {
ragge
1.215
205                         walkf(r->n_leftputjops0);
ragge
1.41
206                         tfree(r->n_left);
207                         l = r->n_right;
ragge
1.1
208                 }
ragge
1.214
209                 nfree(r);
210                 return(l);
ragge
1.155
211         } else ifopty == BITYPE && l->n_op == ICON && r->n_op == ICON ){
ragge
1.1
212
213                 switcho ){
214
ragge
1.159
215                 case PLUS:
216                 case MINUS:
217                 case MUL:
218                 case DIV:
219                 case MOD:
220                         /*
221                          * Do type propagation for simple types here.
222                          * The constant value is correct anyway.
223                          * Maybe this op shortcut should be removed?
224                          */
225                         if (l->n_sp == NULL && r->n_sp == NULL &&
226                             l->n_type < BTMASK && r->n_type < BTMASK) {
227                                 if (l->n_type > r->n_type)
228                                         r->n_type = l->n_type;
229                                 else
230                                         l->n_type = r->n_type;
231                         }
232                         /* FALLTHROUGH */
ragge
1.1
233                 case ULT:
234                 case UGT:
235                 case ULE:
236                 case UGE:
237                 case LT:
238                 case GT:
239                 case LE:
240                 case GE:
241                 case EQ:
ragge
1.48
242                 case NE:
ragge
1.1
243                 case ANDAND:
244                 case OROR:
245                 case AND:
246                 case OR:
247                 case ER:
248                 case LS:
249                 case RS:
ragge
1.200
250                         if (!ISPTR(l->n_type) && !ISPTR(r->n_type)) {
251                                 ifconvallor ) ) {
252                                         nfree(r);
253                                         return(l);
254                                 }
ragge
1.44
255                         }
ragge
1.1
256                         break;
257                 }
ragge
1.44
258         } else if (opty == BITYPE && (l->n_op == FCON || l->n_op == ICON) &&
259             (r->n_op == FCON || r->n_op == ICON) && (o == PLUS || o == MINUS ||
gmcgarry
1.234
260             o == MUL || o == DIV || (o >= EQ && o <= GT) )) {
ragge
1.270
261                 TWORD t;
ragge
1.261
262 #ifndef CC_DIV_0
ragge
1.257
263                 if (o == DIV &&
264                     ((r->n_op == ICON && r->n_lval == 0) ||
265                      (r->n_op == FCON && r->n_dcon == 0.0)))
266                                 goto runtime/* HW dependent */
ragge
1.261
267 #endif
gmcgarry
1.234
268                 if (l->n_op == ICON)
269                         l->n_dcon = FLOAT_CAST(l->n_lvall->n_type);
270                 if (r->n_op == ICON)
271                         r->n_dcon = FLOAT_CAST(r->n_lvalr->n_type);
ragge
1.44
272                 switch(o){
273                 case PLUS:
274                 case MINUS:
275                 case MUL:
276                 case DIV:
277                         switch (o) {
278                         case PLUS:
ragge
1.206
279                                 l->n_dcon = FLOAT_PLUS(l->n_dconr->n_dcon);
280                                 break;
ragge
1.44
281                         case MINUS:
ragge
1.206
282                                 l->n_dcon = FLOAT_MINUS(l->n_dconr->n_dcon);
283                                 break;
ragge
1.44
284                         case MUL:
ragge
1.206
285                                 l->n_dcon = FLOAT_MUL(l->n_dconr->n_dcon);
286                                 break;
ragge
1.44
287                         case DIV:
ragge
1.206
288                                 l->n_dcon = FLOAT_DIV(l->n_dconr->n_dcon);
289                                 break;
ragge
1.44
290                         }
ragge
1.270
291                         t = (l->n_type > r->n_type ? l->n_type : r->n_type);
ragge
1.44
292                         l->n_op = FCON;
ragge
1.270
293                         l->n_type = 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.274
333         p = block(olrINT00);
ragge
1.1
334
335         actions = opact(p);
336
ragge
1.275
337         if (actions & PROML)
338                 p->n_left = intprom(p->n_left);
339
ragge
1.66
340         if (actions & LVAL) { /* check left descendent */
341                 if (notlval(p->n_left)) {
342                         uerror("lvalue required");
stefan
1.186
343                         nfree(p);
344                         return l;
ragge
1.68
345 #ifdef notyet
ragge
1.67
346                 } else {
347                         if ((l->n_type > BTMASK && ISCON(l->n_qual)) ||
348                             (l->n_type <= BTMASK && ISCON(l->n_qual << TSHIFT)))
349                                 if (blevel > 0)
350                                         uerror("lvalue is declared const");
ragge
1.68
351 #endif
ragge
1.67
352                 }
ragge
1.66
353         }
ragge
1.1
354
355         ifactions & NCVTR ){
ragge
1.22
356                 p->n_left = pconvertp->n_left );
ragge
1.1
357                 }
358         else if( !(actions & NCVT ) ){
359                 switchopty ){
360
361                 case BITYPE:
ragge
1.22
362                         p->n_right = pconvertp->n_right );
ragge
1.1
363                 case UTYPE:
ragge
1.22
364                         p->n_left = pconvertp->n_left );
ragge
1.1
365
366                         }
367                 }
368
ragge
1.64
369         if ((actions&PUN) && (o!=CAST))
ragge
1.1
370                 chkpun(p);
371
372         ifactions & (TYPL|TYPR) ){
373
ragge
1.22
374                 q = (actions&TYPL) ? p->n_left : p->n_right;
ragge
1.1
375
ragge
1.22
376                 p->n_type = q->n_type;
ragge
1.66
377                 p->n_qual = q->n_qual;
ragge
1.29
378                 p->n_df = q->n_df;
ragge
1.252
379                 p->n_ap = q->n_ap;
ragge
1.1
380                 }
381
382         ifactions & CVTL ) p = convertpCVTL );
383         ifactions & CVTR ) p = convertpCVTR );
384         ifactions & TYMATCH ) p = tymatch(p);
385         ifactions & PTMATCH ) p = ptmatch(p);
386
387         ifactions & OTHER ){
ragge
1.252
388                 struct symtab *sp1;
ragge
1.225
389
ragge
1.22
390                 l = p->n_left;
391                 r = p->n_right;
ragge
1.1
392
393                 switch(o){
394
395                 case NAME:
ragge
1.203
396                         cerror("buildtree NAME");
ragge
1.1
397
398                 case STREF:
399                         /* p->x turned into *(p+offset) */
400                         /* rhs must be a name; check correctness */
401
ragge
1.23
402                         /* Find member symbol struct */
403                         if (l->n_type != PTR+STRTY && l->n_type != PTR+UNIONTY){
404                                 uerror("struct or union required");
405                                 break;
406                         }
407
ragge
1.252
408                         if ((sp1 = strmemb(l->n_ap)) == NULL) {
ragge
1.23
409                                 uerror("undefined struct or union");
stefan
1.190
410                                 break;
411                         }
ragge
1.23
412
ragge
1.252
413                         if ((sp = findmember(sp1r->n_name)) == 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.252
432                         p->n_ap = l->n_ap;
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.252
447                                 p->n_ap = l->n_ap;
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) {
ragge
1.274
474                                 p->n_left = makety(lINT000);
ragge
1.150
475                         } else if (p->n_type == UCHAR || p->n_type == USHORT) {
ragge
1.274
476                                 p->n_left = makety(lUNSIGNED000);
ragge
1.150
477                         }
478                         l = p->n_left;
479                         p->n_type = l->n_type;
480                         p->n_qual = l->n_qual;
481                         p->n_df = l->n_df;
ragge
1.252
482                         p->n_ap = l->n_ap;
ragge
1.150
483
484                         /* FALLTHROUGH */
ragge
1.95
485                 case LSEQ:
ragge
1.150
486                 case RSEQ/* ...but not for assigned types */
ragge
1.252
487                         if(tsize(r->n_typer->n_dfr->n_ap) > SZINT)
ragge
1.274
488                                 p->n_right = makety(rINT000);
ragge
1.1
489                         break;
490
491                 case RETURN:
492                 case ASSIGN:
493                 case CAST:
494                         /* structure assignment */
495                         /* take the addresses of the two sides; then make an
ragge
1.2
496                          * operator using STASG and
497                          * the addresses of left and right */
ragge
1.1
498
ragge
1.252
499                         if (strmemb(l->n_ap) != strmemb(r->n_ap))
500                                 uerror("assignment of different structures");
501
502                         r = buildtree(ADDROFrNIL);
503
504                         l = block(STASGlrr->n_typer->n_dfr->n_ap);
505                         l = clocal(l);
ragge
1.1
506
ragge
1.252
507                         ifo == RETURN ){
508                                 nfree(p);
509                                 p = l;
ragge
1.1
510                                 break;
ragge
1.252
511                         }
512
513                         p->n_op = UMUL;
514                         p->n_left = l;
515                         p->n_right = NIL;
516                         break;
517
ragge
1.266
518                 case QUEST/* fixup types of : */
519                         if (r->n_left->n_type != p->n_type)
520                                 r->n_left = makety(r->n_leftp->n_type,
521                                     p->n_qualp->n_dfp->n_ap);
522                         if (r->n_right->n_type != p->n_type)
523                                 r->n_right = makety(r->n_rightp->n_type,
524                                     p->n_qualp->n_dfp->n_ap);
525                         break;
526
ragge
1.1
527                 case COLON:
528                         /* structure colon */
529
ragge
1.252
530                         if (strmemb(l->n_ap) != strmemb(r->n_ap))
ragge
1.26
531                                 uerror"type clash in conditional" );
ragge
1.1
532                         break;
533
534                 case CALL:
ragge
1.45
535                         p->n_right = r = strargs(p->n_right);
ragge
1.171
536                         p = funcode(p);
537                         /* FALLTHROUGH */
ragge
1.95
538                 case UCALL:
ragge
1.23
539                         if (!ISPTR(l->n_type))
540                                 uerror("illegal function");
ragge
1.22
541                         p->n_type = DECREF(l->n_type);
ragge
1.23
542                         if (!ISFTN(p->n_type))
543                                 uerror("illegal function");
544                         p->n_type = DECREF(p->n_type);
ragge
1.252
545                         p->n_df = l->n_df+1/* add one for prototypes */
546                         p->n_ap = l->n_ap;
ragge
1.23
547                         if (p->n_type == STRTY || p->n_type == UNIONTY) {
ragge
1.1
548                                 /* function returning structure */
549                                 /*  make function really return ptr to str., with * */
550
ragge
1.22
551                                 p->n_op += STCALL-CALL;
ragge
1.23
552                                 p->n_type = INCREF(p->n_type);
ragge
1.149
553                                 p = clocal(p); /* before recursing */
ragge
1.94
554                                 p = buildtree(UMULpNIL);
ragge
1.1
555
556                                 }
557                         break;
558
559                 default:
560                         cerror"other code %d"o );
561                         }
562
563                 }
564
ragge
1.11
565         /*
566          * Allow (void)0 casts.
567          * XXX - anything on the right side must be possible to cast.
568          * XXX - remove void types further on.
569          */
ragge
1.50
570         if (p->n_op == CAST && p->n_type == VOID &&
ragge
1.22
571             p->n_right->n_op == ICON)
ragge
1.50
572                 p->n_right->n_type = VOID;
ragge
1.11
573
ragge
1.68
574         if (actions & CVTO)
575                 p = oconvert(p);
ragge
1.1
576         p = clocal(p);
577
ragge
1.30
578 #ifdef PCC_DEBUG
ragge
1.74
579         if (bdebug) {
580                 printf("End of buildtree:\n");
ragge
1.68
581                 fwalk(peprint0);
ragge
1.74
582         }
ragge
1.30
583 #endif
ragge
1.1
584
585         return(p);
586
587         }
588
ragge
1.218
589 /* Find a member in a struct or union.  May be an unnamed member */
590 static struct symtab *
591 findmember(struct symtab *spchar *s)
592 {
593         struct symtab *sp2, *sp3;
594
595         for (; sp != NULLsp = sp->snext) {
596                 if (sp->sname[0] == '*') {
597                         /* unnamed member, recurse down */
ragge
1.252
598                         if ((sp2 = findmember(strmemb(sp->sap), s))) {
ragge
1.218
599                                 sp3 = tmpalloc(sizeof (struct symtab));
600                                 *sp3 = *sp2;
601                                 sp3->soffset += sp->soffset;
602                                 return sp3;
603                         }
604                 } else if (sp->sname == s)
605                         return sp;
606         }
607         return NULL;
608 }
609
610
ragge
1.107
611 /*
ragge
1.214
612  * Check if there will be a lost label destination inside of a ?:
613  * It cannot be reached so just print it out.
614  */
ragge
1.269
615 void
ragge
1.215
616 putjops(NODE *pvoid *arg)
ragge
1.214
617 {
618         if (p->n_op == COMOP && p->n_left->n_op == GOTO)
619                 plabel(p->n_left->n_left->n_lval+1);
620 }
621
622 /*
ragge
1.199
623  * Build a name node based on a symtab entry.
624  * broken out from buildtree().
625  */
626 NODE *
627 nametree(struct symtab *sp)
628 {
629         NODE *p;
630
ragge
1.252
631         p = block(NAMENILNILsp->stypesp->sdfsp->sap);
ragge
1.199
632         p->n_qual = sp->squal;
633         p->n_sp = sp;
634
635 #ifndef NO_C_BUILTINS
636         if (sp->sname[0] == '_' && strncmp(sp->sname"__builtin_"10) == 0)
637                 return p;  /* do not touch builtins here */
638         
639 #endif
640
641         if (sp->sflags & STNODE) {
642                 /* Generated for optimizer */
643                 p->n_op = TEMP;
644                 p->n_rval = sp->soffset;
645         }
646
647 #ifdef GCC_COMPAT
648         /* Get a label name */
649         if (sp->sflags == SLBLNAME) {
650                 p->n_type = VOID;
651         }
652 #endif
653         if (sp->stype == UNDEF) {
654                 uerror("%s undefined"sp->sname);
655                 /* make p look reasonable */
656                 p->n_type = INT;
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.274
679         q = block(NAMENILNILt00);
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.273
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)
ragge
1.274
761                         p = makety(ptd000);
ragge
1.264
762                 if (tr != td)
ragge
1.274
763                         q = makety(qtd000);
ragge
1.264
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 =