Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20110809163956

Diff

Diff from 1.299 to:

Annotations

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

Annotated File View

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