Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20110727175131

Diff

Diff from 1.292 to:

Annotations

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

Annotated File View

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