Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20141012195724

Diff

Diff from 1.344 to:

Annotations

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

Annotated File View

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