Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20100619073458

Diff

Diff from 1.250 to:

Annotations

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

Annotated File View

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