Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20120901081826

Diff

Diff from 1.312 to:

Annotations

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

Annotated File View

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