Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20160209213633

Diff

Diff from 1.371 to:

Annotations

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

Annotated File View

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