Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20160418163413

Diff

Diff from 1.375 to:

Annotations

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

Annotated File View

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