Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20110805081440

Diff

Diff from 1.297 to:

Annotations

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

Annotated File View

ragge
1.297
1 /*      $Id: trees.c,v 1.297 2011/08/05 08:14:40 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;
335                         }
336                         nfree(r);
ragge
1.236
337                         nfree(l);
ragge
1.297
338                         return bcon(n);
ragge
1.1
339                 }
ragge
1.44
340         }
ragge
1.261
341 #ifndef CC_DIV_0
otto
1.170
342 runtime:
ragge
1.261
343 #endif
ragge
1.30
344         /* its real; we must make a new node */
ragge
1.1
345
ragge
1.274
346         p = block(olrINT00);
ragge
1.1
347
348         actions = opact(p);
349
ragge
1.275
350         if (actions & PROML)
351                 p->n_left = intprom(p->n_left);
352
ragge
1.66
353         if (actions & LVAL) { /* check left descendent */
354                 if (notlval(p->n_left)) {
355                         uerror("lvalue required");
stefan
1.186
356                         nfree(p);
357                         return l;
ragge
1.68
358 #ifdef notyet
ragge
1.67
359                 } else {
360                         if ((l->n_type > BTMASK && ISCON(l->n_qual)) ||
361                             (l->n_type <= BTMASK && ISCON(l->n_qual << TSHIFT)))
362                                 if (blevel > 0)
363                                         uerror("lvalue is declared const");
ragge
1.68
364 #endif
ragge
1.67
365                 }
ragge
1.66
366         }
ragge
1.1
367
368         ifactions & NCVTR ){
ragge
1.22
369                 p->n_left = pconvertp->n_left );
ragge
1.1
370                 }
371         else if( !(actions & NCVT ) ){
372                 switchopty ){
373
374                 case BITYPE:
ragge
1.22
375                         p->n_right = pconvertp->n_right );
ragge
1.1
376                 case UTYPE:
ragge
1.22
377                         p->n_left = pconvertp->n_left );
ragge
1.1
378
379                         }
380                 }
381
ragge
1.64
382         if ((actions&PUN) && (o!=CAST))
ragge
1.1
383                 chkpun(p);
384
385         ifactions & (TYPL|TYPR) ){
386
ragge
1.22
387                 q = (actions&TYPL) ? p->n_left : p->n_right;
ragge
1.1
388
ragge
1.22
389                 p->n_type = q->n_type;
ragge
1.66
390                 p->n_qual = q->n_qual;
ragge
1.29
391                 p->n_df = q->n_df;
ragge
1.252
392                 p->n_ap = q->n_ap;
ragge
1.1
393                 }
394
395         ifactions & CVTL ) p = convertpCVTL );
396         ifactions & CVTR ) p = convertpCVTR );
397         ifactions & TYMATCH ) p = tymatch(p);
398         ifactions & PTMATCH ) p = ptmatch(p);
399
400         ifactions & OTHER ){
ragge
1.252
401                 struct symtab *sp1;
ragge
1.225
402
ragge
1.22
403                 l = p->n_left;
404                 r = p->n_right;
ragge
1.1
405
406                 switch(o){
407
408                 case NAME:
ragge
1.203
409                         cerror("buildtree NAME");
ragge
1.1
410
411                 case STREF:
412                         /* p->x turned into *(p+offset) */
413                         /* rhs must be a name; check correctness */
414
ragge
1.23
415                         /* Find member symbol struct */
416                         if (l->n_type != PTR+STRTY && l->n_type != PTR+UNIONTY){
417                                 uerror("struct or union required");
418                                 break;
419                         }
420
ragge
1.252
421                         if ((sp1 = strmemb(l->n_ap)) == NULL) {
ragge
1.23
422                                 uerror("undefined struct or union");
stefan
1.190
423                                 break;
424                         }
ragge
1.23
425
ragge
1.252
426                         if ((sp = findmember(sp1r->n_name)) == NULL) {
ragge
1.218
427                                 uerror("member '%s' not declared"r->n_name);
stefan
1.190
428                                 break;
429                         }
ragge
1.23
430
431                         r->n_sp = sp;
432                         p = stref(p);
433                         break;
434
ragge
1.94
435                 case UMUL:
ragge
1.93
436                         if (l->n_op == ADDROF) {
ragge
1.41
437                                 nfree(p);
ragge
1.292
438                                 p = nfree(l);
ragge
1.41
439                         }
ragge
1.22
440                         if( !ISPTR(l->n_type))uerror("illegal indirection");
441                         p->n_type = DECREF(l->n_type);
ragge
1.67
442                         p->n_qual = DECREF(l->n_qual);
ragge
1.29
443                         p->n_df = l->n_df;
ragge
1.252
444                         p->n_ap = l->n_ap;
ragge
1.1
445                         break;
446
ragge
1.93
447                 case ADDROF:
ragge
1.22
448                         switchl->n_op ){
ragge
1.1
449
ragge
1.94
450                         case UMUL:
ragge
1.41
451                                 nfree(p);
ragge
1.292
452                                 p = nfree(l);
453                                 /* FALLTHROUGH */
ragge
1.130
454                         case TEMP:
ragge
1.1
455                         case NAME:
ragge
1.68
456                                 p->n_type = INCREF(l->n_type);
457                                 p->n_qual = INCQAL(l->n_qual);
ragge
1.29
458                                 p->n_df = l->n_df;
ragge
1.252
459                                 p->n_ap = l->n_ap;
ragge
1.1
460                                 break;
461
462                         case COMOP:
ragge
1.41
463                                 nfree(p);
ragge
1.93
464                                 lr = buildtree(ADDROFl->n_rightNIL);
ragge
1.22
465                                 p = buildtreeCOMOPl->n_leftlr );
ragge
1.41
466                                 nfree(l);
ragge
1.1
467                                 break;
468
469                         case QUEST:
ragge
1.93
470                                 lr = buildtreeADDROFl->n_right->n_rightNIL );
471                                 ll = buildtreeADDROFl->n_right->n_leftNIL );
ragge
1.41
472                                 nfree(p); nfree(l->n_right);
ragge
1.22
473                                 p = buildtreeQUESTl->n_leftbuildtreeCOLONlllr ) );
ragge
1.41
474                                 nfree(l);
ragge
1.1
475                                 break;
476
477                         default:
ragge
1.22
478                                 uerror("unacceptable operand of &: %d"l->n_op );
ragge
1.1
479                                 break;
480                                 }
481                         break;
482
483                 case LS:
ragge
1.150
484                 case RS/* must make type size at least int... */
485                         if (p->n_type == CHAR || p->n_type == SHORT) {
ragge
1.274
486                                 p->n_left = makety(lINT000);
ragge
1.150
487                         } else if (p->n_type == UCHAR || p->n_type == USHORT) {
ragge
1.274
488                                 p->n_left = makety(lUNSIGNED000);
ragge
1.150
489                         }
490                         l = p->n_left;
491                         p->n_type = l->n_type;
492                         p->n_qual = l->n_qual;
493                         p->n_df = l->n_df;
ragge
1.252
494                         p->n_ap = l->n_ap;
ragge
1.150
495
496                         /* FALLTHROUGH */
ragge
1.95
497                 case LSEQ:
ragge
1.150
498                 case RSEQ/* ...but not for assigned types */
ragge
1.252
499                         if(tsize(r->n_typer->n_dfr->n_ap) > SZINT)
ragge
1.274
500                                 p->n_right = makety(rINT000);
ragge
1.1
501                         break;
502
503                 case RETURN:
504                 case ASSIGN:
505                 case CAST:
506                         /* structure assignment */
507                         /* take the addresses of the two sides; then make an
ragge
1.2
508                          * operator using STASG and
509                          * the addresses of left and right */
ragge
1.1
510
ragge
1.252
511                         if (strmemb(l->n_ap) != strmemb(r->n_ap))
512                                 uerror("assignment of different structures");
513
514                         r = buildtree(ADDROFrNIL);
515
516                         l = block(STASGlrr->n_typer->n_dfr->n_ap);
517                         l = clocal(l);
ragge
1.1
518
ragge
1.252
519                         ifo == RETURN ){
520                                 nfree(p);
521                                 p = l;
ragge
1.1
522                                 break;
ragge
1.252
523                         }
524
525                         p->n_op = UMUL;
526                         p->n_left = l;
527                         p->n_right = NIL;
528                         break;
529
ragge
1.266
530                 case QUEST/* fixup types of : */
531                         if (r->n_left->n_type != p->n_type)
532                                 r->n_left = makety(r->n_leftp->n_type,
533                                     p->n_qualp->n_dfp->n_ap);
534                         if (r->n_right->n_type != p->n_type)
535                                 r->n_right = makety(r->n_rightp->n_type,
536                                     p->n_qualp->n_dfp->n_ap);
537                         break;
538
ragge
1.1
539                 case COLON:
540                         /* structure colon */
541
ragge
1.252
542                         if (strmemb(l->n_ap) != strmemb(r->n_ap))
ragge
1.26
543                                 uerror"type clash in conditional" );
ragge
1.1
544                         break;
545
546                 case CALL:
ragge
1.45
547                         p->n_right = r = strargs(p->n_right);
ragge
1.171
548                         p = funcode(p);
549                         /* FALLTHROUGH */
ragge
1.95
550                 case UCALL:
ragge
1.23
551                         if (!ISPTR(l->n_type))
552                                 uerror("illegal function");
ragge
1.22
553                         p->n_type = DECREF(l->n_type);
ragge
1.23
554                         if (!ISFTN(p->n_type))
555                                 uerror("illegal function");
556                         p->n_type = DECREF(p->n_type);
ragge
1.252
557                         p->n_df = l->n_df+1/* add one for prototypes */
558                         p->n_ap = l->n_ap;
ragge
1.23
559                         if (p->n_type == STRTY || p->n_type == UNIONTY) {
ragge
1.1
560                                 /* function returning structure */
561                                 /*  make function really return ptr to str., with * */
562
ragge
1.22
563                                 p->n_op += STCALL-CALL;
ragge
1.23
564                                 p->n_type = INCREF(p->n_type);
ragge
1.149
565                                 p = clocal(p); /* before recursing */
ragge
1.94
566                                 p = buildtree(UMULpNIL);
ragge
1.1
567
568                                 }
569                         break;
570
571                 default:
572                         cerror"other code %d"o );
573                         }
574
575                 }
576
ragge
1.11
577         /*
578          * Allow (void)0 casts.
579          * XXX - anything on the right side must be possible to cast.
580          * XXX - remove void types further on.
581          */
ragge
1.50
582         if (p->n_op == CAST && p->n_type == VOID &&
ragge
1.22
583             p->n_right->n_op == ICON)
ragge
1.50
584                 p->n_right->n_type = VOID;
ragge
1.11
585
ragge
1.68
586         if (actions & CVTO)
587                 p = oconvert(p);
ragge
1.1
588         p = clocal(p);
589
ragge
1.30
590 #ifdef PCC_DEBUG
ragge
1.74
591         if (bdebug) {
592                 printf("End of buildtree:\n");
ragge
1.68
593                 fwalk(peprint0);
ragge
1.74
594         }
ragge
1.30
595 #endif
ragge
1.1
596
597         return(p);
598
599         }
600
ragge
1.218
601 /* Find a member in a struct or union.  May be an unnamed member */
602 static struct symtab *
603 findmember(struct symtab *spchar *s)
604 {
605         struct symtab *sp2, *sp3;
606
607         for (; sp != NULLsp = sp->snext) {
608                 if (sp->sname[0] == '*') {
609                         /* unnamed member, recurse down */
ragge
1.252
610                         if ((sp2 = findmember(strmemb(sp->sap), s))) {
ragge
1.218
611                                 sp3 = tmpalloc(sizeof (struct symtab));
612                                 *sp3 = *sp2;
613                                 sp3->soffset += sp->soffset;
614                                 return sp3;
615                         }
616                 } else if (sp->sname == s)
617                         return sp;
618         }
619         return NULL;
620 }
621
622
ragge
1.107
623 /*
ragge
1.214
624  * Check if there will be a lost label destination inside of a ?:
625  * It cannot be reached so just print it out.
626  */
ragge
1.269
627 void
ragge
1.215
628 putjops(NODE *pvoid *arg)
ragge
1.214
629 {
630         if (p->n_op == COMOP && p->n_left->n_op == GOTO)
ragge
1.297
631                 plabel((int)p->n_left->n_left->n_lval+1);
ragge
1.214
632 }
633
634 /*
ragge
1.199
635  * Build a name node based on a symtab entry.
636  * broken out from buildtree().
637  */
638 NODE *
639 nametree(struct symtab *sp)
640 {
641         NODE *p;
642
ragge
1.252
643         p = block(NAMENILNILsp->stypesp->sdfsp->sap);
ragge
1.199
644         p->n_qual = sp->squal;
645         p->n_sp = sp;
646
647 #ifndef NO_C_BUILTINS
648         if (sp->sname[0] == '_' && strncmp(sp->sname"__builtin_"10) == 0)
649                 return p;  /* do not touch builtins here */
650         
651 #endif
652
653         if (sp->sflags & STNODE) {
654                 /* Generated for optimizer */
655                 p->n_op = TEMP;
656                 p->n_rval = sp->soffset;
657         }
658
659 #ifdef GCC_COMPAT
660         /* Get a label name */
661         if (sp->sflags == SLBLNAME) {
662                 p->n_type = VOID;
663         }
664 #endif
665         if (sp->stype == UNDEF) {
666                 uerror("%s undefined"sp->sname);
667                 /* make p look reasonable */
668                 p->n_type = INT;
669                 p->n_df = NULL;
670                 defid(pSNULL);
671         }
672         if (sp->sclass == MOE) {
673                 p->n_op = ICON;
674                 p->n_lval = sp->soffset;
675                 p->n_df = NULL;
676                 p->n_sp = NULL;
677         }
678         return clocal(p);
679 }
680
681 /*
ragge
1.241
682  * Cast a node to another type by inserting a cast.
ragge
1.240
683  * Just a nicer interface to buildtree.
684  * Returns the new tree.
685  */
686 NODE *
687 cast(NODE *pTWORD tTWORD u)
688 {
689         NODE *q;
690
ragge
1.274
691         q = block(NAMENILNILt00);
ragge
1.240
692         q->n_qual = u;
693         q = buildtree(CASTqp);
694         p = q->n_right;
695         nfree(q->n_left);
696         nfree(q);
697         return p;
698 }
699
700 /*
ragge
1.241
701  * Cast and complain if necessary by not inserining a cast.
702  */
703 NODE *
ragge
1.252
704 ccast(NODE *pTWORD tTWORD uunion dimfun *dfstruct attr *ap)
ragge
1.241
705 {
706         NODE *q;
707
708         /* let buildtree do typechecking (and casting) */ 
ragge
1.252
709         q = block(NAMENILNILtdfap);
ragge
1.241
710         p = buildtree(ASSIGNqp);
711         nfree(p->n_left);
712         q = optim(p->n_right);
713         nfree(p);
714         return q;
715 }
716
717 /*
ragge
1.284
718  * Do an actual cast of a constant (if possible).
719  * Routine assumes 2-complement (is there anything else today?)
720  * Returns 1 if handled, 0 otherwise.
721  */
722 int
723 concast(NODE *pTWORD t)
724 {
725         extern short sztable[];
726         CONSZ val;
727
728         if (p->n_op != ICON && p->n_op != FCON/* only constants */
729                 return 0;
730         if (p->n_op == ICON && p->n_sp != NULL) { /* no addresses */
731                 if (t == BOOL) {
732                         p->n_lval = 1p->n_type = BOOLp->n_sp = NULL;
733                         return 1;
734                 }
735                 return 0;
736         }
737         if ((p->n_type & TMASK) || (t & TMASK)) /* no cast of pointers */
738                 return 0;
739
740 //printf("concast till %d\n", t);
741 //fwalk(p, eprint, 0);
742
743 #define TYPMSK(y) ((((1LL << (y-1))-1) << 1) | 1)
744         if (p->n_op == ICON) {
745                 val = p->n_lval;
746
747                 if (t == BOOL) {
748                         if (val)
749                                 p->n_lval = 1;
750                 } else if (t <= ULONGLONG) {
751                         p->n_lval = val & TYPMSK(sztable[t]);
752                         if (!ISUNSIGNED(t)) {
753                                 if (val & (1LL << (sztable[t]-1)))
754                                         p->n_lval |= ~TYPMSK(sztable[t]);
755                         }
756                 } else if (t <= LDOUBLE) {
757                         p->n_op = FCON;
758                         p->n_dcon = FLOAT_CAST(valp->n_type);
759                 }
760         } else { /* p->n_op == FCON */
761                 if (t == BOOL) {
762                         p->n_op = ICON;
763                         p->n_lval = FLOAT_NE(p->n_dcon,0.0);
764                         p->n_sp = NULL;
765                 } else if (t <= ULONGLONG) {
766                         p->n_op = ICON;
767                         p->n_lval = ISUNSIGNED(t) ? /* XXX FIXME */
768                             ((U_CONSZ)p->n_dcon) : p->n_dcon;
769                         p->n_sp = NULL;
770                 } else {
771                         p->n_dcon = t == FLOAT ? (float)p->n_dcon :
772                             t == DOUBLE ? (double)p->n_dcon : p->n_dcon;
773                 }
774         }
775         p->n_type = t;
776 //fwalk(p, eprint, 0);
777         return 1;
778 }
779
780 /*
ragge
1.107
781  * Do a conditional branch.
782  */
783 void
784 cbranch(NODE *pNODE *q)
785 {
786         p = buildtree(CBRANCHpq);
787         if (p->n_left->n_op == ICON) {
ragge
1.208
788                 if (p->n_left->n_lval != 0) {
ragge
1.297
789                         branch((int)q->n_lval); /* branch always */
ragge
1.208
790                         reached = 0;
791                 }
ragge
1.107
792                 tfree(p);
793                 tfree(q);
794                 return;
795         }
796         ecomp(p);
797 }
798
ragge
1.1
799 NODE *
ragge
1.45
800 strargsp ) register NODE *p;  { /* rewrite structure flavored arguments */
ragge
1.1
801
ragge
1.45
802         ifp->n_op == CM ){
803                 p->n_left = strargsp->n_left );
804                 p->n_right = strargsp->n_right );
ragge
1.1
805                 returnp );
806                 }
807
ragge
1.22
808         ifp->n_type == STRTY || p->n_type == UNIONTY ){
ragge
1.252
809                 p = block(STARGpNILp->n_typep->n_dfp->n_ap);
ragge
1.93
810                 p->n_left = buildtreeADDROFp->n_leftNIL );
ragge
1.1
811                 p = clocal(p);
812                 }
813         returnp );
ragge
1.2
814 }
ragge
1.1
815
ragge
1.2
816 /*
817  * apply the op o to the lval part of p; if binary, rhs is val
818  */
819 int
820 conval(NODE *pint oNODE *q)
821 {
ragge
1.264
822         TWORD tl = p->n_typetr = q->n_typetd;
ragge
1.1
823         int iu;
824         CONSZ val;
ragge
1.159
825         U_CONSZ v1v2;
ragge
1.1
826
ragge
1.22
827         val = q->n_lval;
ragge
1.264
828
829         /* make both sides same type */
ragge
1.273
830         if (tl < BTMASK && tr < BTMASK) {
ragge
1.264
831                 td = tl > tr ? tl : tr;
832                 if (td < INT)
833                         td = INT;
834                 u = ISUNSIGNED(td);
835                 if (tl != td)
ragge
1.274
836                         p = makety(ptd000);
ragge
1.264
837                 if (tr != td)
ragge
1.274
838                         q = makety(qtd000);
ragge
1.264
839         } else
840                 u = ISUNSIGNED(tl) || ISUNSIGNED(tr);
ragge
1.1
841         ifu && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE);
842
ragge
1.23
843         if (p->n_sp != NULL && q->n_sp != NULL)
844                 return(0);
845         if (q->n_sp != NULL && o != PLUS)
846                 return(0);
847         if (p->n_sp != NULL && o != PLUS && o != MINUS)
848                 return(0);
ragge
1.264
849
ragge
1.161
850         v1 = p->n_lval;
851         v2 = q->n_lval;
ragge
1.1
852         switcho ){
853
854         case PLUS:
ragge
1.22
855                 p->n_lval += val;
ragge
1.23
856                 if (p->n_sp == NULL) {
ragge
1.237
857                         p->n_right = q->n_right;
ragge
1.22
858                         p->n_type = q->n_type;
ragge
1.23
859                 }
ragge
1.1
860                 break;
861         case MINUS:
ragge
1.22
862                 p->n_lval -= val;
ragge
1.1
863                 break;
864         case MUL:
ragge
1.22
865                 p->n_lval *= val;
ragge
1.1
866                 break;
867         case DIV:
ragge
1.46
868                 if (val == 0)
869                         uerror("division by 0");
ragge
1.159
870                 else  {
871                         if (u) {
872                                 v1 /= v2;
873                                 p->n_lval = v1;
874                         } else
875                                 p->n_lval /= val;
876                 }
ragge
1.1
877                 break;
878         case MOD:
ragge
1.46
879                 if (val == 0)
880                         uerror("division by 0");
ragge
1.159
881                 else  {
882                         if (u) {
883                                 v1 %= v2;
884                                 p->n_lval = v1;
885                         } else
886                                 p->n_lval %= val;
887                 }
ragge
1.1
888                 break;
889         case AND:
ragge
1.22
890                 p->n_lval &= val;
ragge
1.1
891                 break;
892         case OR:
ragge
1.22
893                 p->n_lval |= val;
ragge
1.1
894                 break;
895         case ER:
ragge
1.22
896                 p->n_lval ^= val;
ragge
1.1
897                 break;
898         case LS: