Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20140813201859

Diff

Diff from 1.335 to:

Annotations

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

Annotated File View

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