Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20121022092949

Diff

Diff from 1.320 to:

Annotations

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

Annotated File View

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