Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20140620070448

Diff

Diff from 1.329 to:

Annotations

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

Annotated File View

plunky
1.329
1 /*      $Id: trees.c,v 1.329 2014/06/20 07:04:48 plunky 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 */
ragge
1.328
361                 if ((cdope(o) & SIMPFLG) && ISINTEGER(l->n_type) && 
362                     l->n_type != BOOL
ragge
1.309
363                         r = ccast(rl->n_typel->n_quall->n_dfl->n_ap);
364
365                 r = buildtree(UNASG occopy(l), r);
366                 r = buildtree(ASSIGNlr);
367                 l = q;
368                 o = COMOP;
369         } else if (o == INCR || o == DECR) {
370                 /*
371                  * Rewrite to (t=d,d=d+1,t)
372                  */
373                 if (has_se(l)) {
374                         ll = l->n_left;
375
376                         q = cstknode(ll->n_typell->n_dfll->n_ap);
377                         l->n_left = ccopy(q);
378                         q = buildtree(ASSIGNqll);
379                 } else 
380                         q = bcon(0); /* No side effects */
381
382                 /* Boolean has special syntax. */
383                 if (l->n_type == BOOL) {
384                         r = rewincop(lro == INCR ? ASSIGN : EREQ);
385                 } else
386                         r = rewincop(lro == INCR ? PLUSEQ : MINUSEQ);
387                 l = q;
388                 o = COMOP;
ragge
1.44
389         }
ragge
1.309
390
391
ragge
1.261
392 #ifndef CC_DIV_0
otto
1.170
393 runtime:
ragge
1.261
394 #endif
ragge
1.30
395         /* its real; we must make a new node */
ragge
1.1
396
ragge
1.274
397         p = block(olrINT00);
ragge
1.1
398
399         actions = opact(p);
400
ragge
1.275
401         if (actions & PROML)
402                 p->n_left = intprom(p->n_left);
403
ragge
1.66
404         if (actions & LVAL) { /* check left descendent */
405                 if (notlval(p->n_left)) {
406                         uerror("lvalue required");
stefan
1.186
407                         nfree(p);
408                         return l;
ragge
1.68
409 #ifdef notyet
ragge
1.67
410                 } else {
411                         if ((l->n_type > BTMASK && ISCON(l->n_qual)) ||
412                             (l->n_type <= BTMASK && ISCON(l->n_qual << TSHIFT)))
413                                 if (blevel > 0)
414                                         uerror("lvalue is declared const");
ragge
1.68
415 #endif
ragge
1.67
416                 }
ragge
1.66
417         }
ragge
1.1
418
419         ifactions & NCVTR ){
ragge
1.22
420                 p->n_left = pconvertp->n_left );
ragge
1.1
421                 }
422         else if( !(actions & NCVT ) ){
423                 switchopty ){
424
425                 case BITYPE:
ragge
1.22
426                         p->n_right = pconvertp->n_right );
plunky
1.319
427                         /* FALLTHROUGH */
ragge
1.1
428                 case UTYPE:
ragge
1.22
429                         p->n_left = pconvertp->n_left );
ragge
1.1
430
431                         }
432                 }
433
ragge
1.64
434         if ((actions&PUN) && (o!=CAST))
ragge
1.1
435                 chkpun(p);
436
437         ifactions & (TYPL|TYPR) ){
438
ragge
1.22
439                 q = (actions&TYPL) ? p->n_left : p->n_right;
ragge
1.1
440
ragge
1.22
441                 p->n_type = q->n_type;
ragge
1.66
442                 p->n_qual = q->n_qual;
ragge
1.29
443                 p->n_df = q->n_df;
ragge
1.252
444                 p->n_ap = q->n_ap;
ragge
1.1
445                 }
446
447         ifactions & CVTL ) p = convertpCVTL );
448         ifactions & CVTR ) p = convertpCVTR );
449         ifactions & TYMATCH ) p = tymatch(p);
450         ifactions & PTMATCH ) p = ptmatch(p);
451
452         ifactions & OTHER ){
ragge
1.252
453                 struct symtab *sp1;
ragge
1.225
454
ragge
1.22
455                 l = p->n_left;
456                 r = p->n_right;
ragge
1.1
457
458                 switch(o){
459
460                 case NAME:
ragge
1.203
461                         cerror("buildtree NAME");
ragge
1.1
462
463                 case STREF:
464                         /* p->x turned into *(p+offset) */
465                         /* rhs must be a name; check correctness */
466
ragge
1.23
467                         /* Find member symbol struct */
468                         if (l->n_type != PTR+STRTY && l->n_type != PTR+UNIONTY){
469                                 uerror("struct or union required");
470                                 break;
471                         }
472
ragge
1.252
473                         if ((sp1 = strmemb(l->n_ap)) == NULL) {
ragge
1.23
474                                 uerror("undefined struct or union");
stefan
1.190
475                                 break;
476                         }
ragge
1.23
477
ragge
1.252
478                         if ((sp = findmember(sp1r->n_name)) == NULL) {
ragge
1.218
479                                 uerror("member '%s' not declared"r->n_name);
stefan
1.190
480                                 break;
481                         }
ragge
1.23
482
483                         r->n_sp = sp;
484                         p = stref(p);
485                         break;
486
ragge
1.94
487                 case UMUL:
ragge
1.93
488                         if (l->n_op == ADDROF) {
ragge
1.41
489                                 nfree(p);
ragge
1.292
490                                 p = nfree(l);
ragge
1.41
491                         }
ragge
1.22
492                         if( !ISPTR(l->n_type))uerror("illegal indirection");
493                         p->n_type = DECREF(l->n_type);
ragge
1.67
494                         p->n_qual = DECREF(l->n_qual);
ragge
1.29
495                         p->n_df = l->n_df;
ragge
1.252
496                         p->n_ap = l->n_ap;
ragge
1.1
497                         break;
498
ragge
1.93
499                 case ADDROF:
ragge
1.22
500                         switchl->n_op ){
ragge
1.1
501
ragge
1.94
502                         case UMUL:
ragge
1.41
503                                 nfree(p);
ragge
1.292
504                                 p = nfree(l);
505                                 /* FALLTHROUGH */
ragge
1.130
506                         case TEMP:
ragge
1.1
507                         case NAME:
ragge
1.68
508                                 p->n_type = INCREF(l->n_type);
509                                 p->n_qual = INCQAL(l->n_qual);
ragge
1.29
510                                 p->n_df = l->n_df;
ragge
1.252
511                                 p->n_ap = l->n_ap;
ragge
1.1
512                                 break;
513
514                         case COMOP:
ragge
1.41
515                                 nfree(p);
ragge
1.93
516                                 lr = buildtree(ADDROFl->n_rightNIL);
ragge
1.22
517                                 p = buildtreeCOMOPl->n_leftlr );
ragge
1.41
518                                 nfree(l);
ragge
1.1
519                                 break;
520
521                         case QUEST:
ragge
1.93
522                                 lr = buildtreeADDROFl->n_right->n_rightNIL );
523                                 ll = buildtreeADDROFl->n_right->n_leftNIL );
ragge
1.41
524                                 nfree(p); nfree(l->n_right);
ragge
1.22
525                                 p = buildtreeQUESTl->n_leftbuildtreeCOLONlllr ) );
ragge
1.41
526                                 nfree(l);
ragge
1.1
527                                 break;
528
529                         default:
ragge
1.22
530                                 uerror("unacceptable operand of &: %d"l->n_op );
ragge
1.1
531                                 break;
532                                 }
533                         break;
534
535                 case LS:
ragge
1.150
536                 case RS/* must make type size at least int... */
537                         if (p->n_type == CHAR || p->n_type == SHORT) {
ragge
1.274
538                                 p->n_left = makety(lINT000);
ragge
1.150
539                         } else if (p->n_type == UCHAR || p->n_type == USHORT) {
ragge
1.274
540                                 p->n_left = makety(lUNSIGNED000);
ragge
1.150
541                         }
542                         l = p->n_left;
543                         p->n_type = l->n_type;
544                         p->n_qual = l->n_qual;
545                         p->n_df = l->n_df;
ragge
1.252
546                         p->n_ap = l->n_ap;
547                         if(tsize(r->n_typer->n_dfr->n_ap) > SZINT)
ragge
1.274
548                                 p->n_right = makety(rINT000);
ragge
1.1
549                         break;
550
551                 case RETURN:
552                 case ASSIGN:
553                 case CAST:
554                         /* structure assignment */
555                         /* take the addresses of the two sides; then make an
ragge
1.2
556                          * operator using STASG and
557                          * the addresses of left and right */
ragge
1.1
558
ragge
1.252
559                         if (strmemb(l->n_ap) != strmemb(r->n_ap))
560                                 uerror("assignment of different structures");
561
562                         r = buildtree(ADDROFrNIL);
563
564                         l = block(STASGlrr->n_typer->n_dfr->n_ap);
565                         l = clocal(l);
ragge
1.1
566
ragge
1.252
567                         ifo == RETURN ){
568                                 nfree(p);
569                                 p = l;
ragge
1.1
570                                 break;
ragge
1.252
571                         }
572
573                         p->n_op = UMUL;
574                         p->n_left = l;
575                         p->n_right = NIL;
576                         break;
577
ragge
1.266
578                 case QUEST/* fixup types of : */
579                         if (r->n_left->n_type != p->n_type)
580                                 r->n_left = makety(r->n_leftp->n_type,
581                                     p->n_qualp->n_dfp->n_ap);
582                         if (r->n_right->n_type != p->n_type)
583                                 r->n_right = makety(r->n_rightp->n_type,
584                                     p->n_qualp->n_dfp->n_ap);
585                         break;
586
ragge
1.1
587                 case COLON:
588                         /* structure colon */
589
ragge
1.252
590                         if (strmemb(l->n_ap) != strmemb(r->n_ap))
ragge
1.26
591                                 uerror"type clash in conditional" );
ragge
1.1
592                         break;
593
594                 case CALL:
ragge
1.45
595                         p->n_right = r = strargs(p->n_right);
ragge
1.171
596                         p = funcode(p);
597                         /* FALLTHROUGH */
ragge
1.95
598                 case UCALL:
ragge
1.23
599                         if (!ISPTR(l->n_type))
600                                 uerror("illegal function");
ragge
1.22
601                         p->n_type = DECREF(l->n_type);
ragge
1.23
602                         if (!ISFTN(p->n_type))
603                                 uerror("illegal function");
604                         p->n_type = DECREF(p->n_type);
ragge
1.252
605                         p->n_df = l->n_df+1/* add one for prototypes */
606                         p->n_ap = l->n_ap;
ragge
1.23
607                         if (p->n_type == STRTY || p->n_type == UNIONTY) {
ragge
1.1
608                                 /* function returning structure */
609                                 /*  make function really return ptr to str., with * */
610
ragge
1.22
611                                 p->n_op += STCALL-CALL;
ragge
1.23
612                                 p->n_type = INCREF(p->n_type);
ragge
1.149
613                                 p = clocal(p); /* before recursing */
ragge
1.94
614                                 p = buildtree(UMULpNIL);
ragge
1.1
615
616                                 }
617                         break;
618
619                 default:
620                         cerror"other code %d"o );
621                         }
622
623                 }
624
ragge
1.11
625         /*
626          * Allow (void)0 casts.
627          * XXX - anything on the right side must be possible to cast.
628          * XXX - remove void types further on.
629          */
ragge
1.50
630         if (p->n_op == CAST && p->n_type == VOID &&
ragge
1.22
631             p->n_right->n_op == ICON)
ragge
1.50
632                 p->n_right->n_type = VOID;
ragge
1.11
633
ragge
1.68
634         if (actions & CVTO)
635                 p = oconvert(p);
ragge
1.1
636         p = clocal(p);
637
ragge
1.30
638 #ifdef PCC_DEBUG
ragge
1.74
639         if (bdebug) {
640                 printf("End of buildtree:\n");
ragge
1.68
641                 fwalk(peprint0);
ragge
1.74
642         }
ragge
1.30
643 #endif
ragge
1.1
644
645         return(p);
646
647         }
648
ragge
1.309
649 /*                      
650  * Rewrite ++/-- to (t=p, p++, t) ops on types that do not act act as usual.
651  */
652 static NODE *
653 rewincop(NODE *p1NODE *p2int op)
654 {
655         NODE *t, *r;
656                 
657         t = cstknode(p1->n_typep1->n_dfp1->n_ap);
658         r = buildtree(ASSIGNccopy(t), ccopy(p1));
659         r = buildtree(COMOPrbuildtree(opp1eve(p2)));
660         return buildtree(COMOPrt);
661 }
662
663
664 /* Find a member in a struct or union.  May be an unnamed member */
ragge
1.218
665 static struct symtab *
666 findmember(struct symtab *spchar *s)
667 {
668         struct symtab *sp2, *sp3;
669
670         for (; sp != NULLsp = sp->snext) {
671                 if (sp->sname[0] == '*') {
672                         /* unnamed member, recurse down */
ragge
1.252
673                         if ((sp2 = findmember(strmemb(sp->sap), s))) {
ragge
1.218
674                                 sp3 = tmpalloc(sizeof (struct symtab));
675                                 *sp3 = *sp2;
676                                 sp3->soffset += sp->soffset;
677                                 return sp3;
678                         }
679                 } else if (sp->sname == s)
680                         return sp;
681         }
682         return NULL;
683 }
684
685
ragge
1.107
686 /*
ragge
1.214
687  * Check if there will be a lost label destination inside of a ?:
688  * It cannot be reached so just print it out.
689  */
ragge
1.269
690 void
ragge
1.215
691 putjops(NODE *pvoid *arg)
ragge
1.214
692 {
693         if (p->n_op == COMOP && p->n_left->n_op == GOTO)
ragge
1.297
694                 plabel((int)p->n_left->n_left->n_lval+1);
ragge
1.214
695 }
696
697 /*
ragge
1.199
698  * Build a name node based on a symtab entry.
699  * broken out from buildtree().
700  */
701 NODE *
702 nametree(struct symtab *sp)
703 {
704         NODE *p;
705
ragge
1.252
706         p = block(NAMENILNILsp->stypesp->sdfsp->sap);
ragge
1.199
707         p->n_qual = sp->squal;
708         p->n_sp = sp;
709
710 #ifndef NO_C_BUILTINS
711         if (sp->sname[0] == '_' && strncmp(sp->sname"__builtin_"10) == 0)
712                 return p;  /* do not touch builtins here */
713         
714 #endif
715
716         if (sp->sflags & STNODE) {
717                 /* Generated for optimizer */
718                 p->n_op = TEMP;
719                 p->n_rval = sp->soffset;
720         }
721
722 #ifdef GCC_COMPAT
723         /* Get a label name */
ragge
1.310
724         if (sp->sflags == SLBLNAME)
725                 sp->stype = p->n_type = VOID;
ragge
1.199
726 #endif
727         if (sp->stype == UNDEF) {
728                 uerror("%s undefined"sp->sname);
729                 /* make p look reasonable */
730                 p->n_type = INT;
731                 p->n_df = NULL;
732                 defid(pSNULL);
733         }
734         if (sp->sclass == MOE) {
735                 p->n_op = ICON;
736                 p->n_lval = sp->soffset;
737                 p->n_df = NULL;
738                 p->n_sp = NULL;
739         }
740         return clocal(p);
741 }
742
743 /*
ragge
1.241
744  * Cast a node to another type by inserting a cast.
ragge
1.240
745  * Just a nicer interface to buildtree.
746  * Returns the new tree.
747  */
748 NODE *
749 cast(NODE *pTWORD tTWORD u)
750 {
751         NODE *q;
752
ragge
1.274
753         q = block(NAMENILNILt00);
ragge
1.240
754         q->n_qual = u;
755         q = buildtree(CASTqp);
756         p = q->n_right;
757         nfree(q->n_left);
758         nfree(q);
759         return p;
760 }
761
762 /*
ragge
1.241
763  * Cast and complain if necessary by not inserining a cast.
764  */
765 NODE *
ragge
1.252
766 ccast(NODE *pTWORD tTWORD uunion dimfun *dfstruct attr *ap)
ragge
1.241
767 {
768         NODE *q;
769
770         /* let buildtree do typechecking (and casting) */ 
ragge
1.252
771         q = block(NAMENILNILtdfap);
ragge
1.241
772         p = buildtree(ASSIGNqp);
773         nfree(p->n_left);
774         q = optim(p->n_right);
775         nfree(p);
776         return q;
777 }
778
779 /*
ragge
1.284
780  * Do an actual cast of a constant (if possible).
781  * Routine assumes 2-complement (is there anything else today?)
782  * Returns 1 if handled, 0 otherwise.
783  */
784 int
785 concast(NODE *pTWORD t)
786 {
787         extern short sztable[];
788         CONSZ val;
789
790         if (p->n_op != ICON && p->n_op != FCON/* only constants */
791                 return 0;
792         if (p->n_op == ICON && p->n_sp != NULL) { /* no addresses */
793                 if (t == BOOL) {
794                         p->n_lval = 1p->n_type = BOOLp->n_sp = NULL;
795                         return 1;
796                 }
797                 return 0;
798         }
ragge
1.305
799         if (((p->n_type & TMASK) && t != BOOL) || (t & TMASK)) /* no pointers */
ragge
1.284
800                 return 0;
801
802 //printf("concast till %d\n", t);
803 //fwalk(p, eprint, 0);
804
805 #define TYPMSK(y) ((((1LL << (y-1))-1) << 1) | 1)
806         if (p->n_op == ICON) {
807                 val = p->n_lval;
808
809                 if (t == BOOL) {
810                         if (val)
811                                 p->n_lval = 1;
812                 } else if (t <= ULONGLONG) {
813                         p->n_lval = val & TYPMSK(sztable[t]);
814                         if (!ISUNSIGNED(t)) {
815                                 if (val & (1LL << (sztable[t]-1)))
816                                         p->n_lval |= ~TYPMSK(sztable[t]);
817                         }
818                 } else if (t <= LDOUBLE) {
819                         p->n_op = FCON;
820                         p->n_dcon = FLOAT_CAST(valp->n_type);
821                 }
822         } else { /* p->n_op == FCON */
823                 if (t == BOOL) {
824                         p->n_op = ICON;
825                         p->n_lval = FLOAT_NE(p->n_dcon,0.0);
826                         p->n_sp = NULL;
827                 } else if (t <= ULONGLONG) {
828                         p->n_op = ICON;
829                         p->n_lval = ISUNSIGNED(t) ? /* XXX FIXME */
830                             ((U_CONSZ)p->n_dcon) : p->n_dcon;
831                         p->n_sp = NULL;
832                 } else {
833                         p->n_dcon = t == FLOAT ? (float)p->n_dcon :
834                             t == DOUBLE ? (double)p->n_dcon : p->n_dcon;
835                 }
836         }
837         p->n_type = t;
838 //fwalk(p, eprint, 0);
839         return 1;
840 }
841
842 /*
ragge
1.107
843  * Do a conditional branch.
844  */
845 void
846 cbranch(NODE *pNODE *q)
847 {
848         p = buildtree(CBRANCHpq);
849         if (p->n_left->n_op == ICON) {
ragge
1.208
850                 if (p->n_left->n_lval != 0) {
ragge
1.297
851                         branch((int)q->n_lval); /* branch always */
ragge
1.208
852                         reached = 0;
853                 }
ragge
1.107
854                 tfree(p);
855                 tfree(q);
856                 return;
857         }
858         ecomp(p);
859 }
860
ragge
1.1
861 NODE *
plunky
1.308
862 strargs(register NODE *p)
863 {
864         /* rewrite structure flavored arguments */
ragge
1.1
865
ragge
1.45
866         ifp->n_op == CM ){
867                 p->n_left = strargsp->n_left );
868                 p->n_right = strargsp->n_right );
ragge
1.1
869                 returnp );
870                 }
871
ragge
1.22
872         ifp->n_type == STRTY || p->n_type == UNIONTY ){
ragge
1.252
873                 p = block(STARGpNILp->n_typep->n_dfp->n_ap);
ragge
1.93
874                 p->n_left = buildtreeADDROFp->n_leftNIL );
ragge
1.1
875                 p = clocal(p);
876                 }
877         returnp );
ragge
1.2
878 }
ragge
1.1
879
ragge
1.2
880 /*
881  * apply the op o to the lval part of p; if binary, rhs is val
882  */
883 int
884 conval(NODE *pint oNODE *q)
885 {
ragge
1.264
886         TWORD tl = p->n_typetr = q->n_typetd;
ragge
1.1
887         int iu;
888         CONSZ val;
ragge
1.159
889         U_CONSZ v1v2;
ragge
1.1
890
ragge
1.22
891         val = q->n_lval;
ragge
1.264
892
893         /* make both sides same type */
ragge
1.273
894         if (tl < BTMASK && tr < BTMASK) {
ragge
1.264
895                 td = tl > tr ? tl : tr;
896                 if (td < INT)
897                         td = INT;
898                 u = ISUNSIGNED(td);
899                 if (tl != td)
ragge
1.274
900                         p = makety(ptd000);
ragge
1.264
901                 if (tr != td)
ragge
1.274
902                         q = makety(qtd000);
ragge
1.264
903         } else
904                 u = ISUNSIGNED(tl) || ISUNSIGNED(tr);
ragge
1.1
905         ifu && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE);
906