Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20110407185015

Diff

Diff from 1.274 to:

Annotations

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

Annotated File View

ragge
1.274
1 /*      $Id: trees.c,v 1.274 2011/04/07 18:50:16 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.269
80 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.271
167         if (o == ANDAND || o == OROR || o == NOT) {
168                 if (l->n_op == FCON) {
169                         p = bcon(!FLOAT_ISZERO(l->n_dcon));
170                         nfree(l);
171                         l = p;
172                 }
173                 if (o != NOT && r->n_op == FCON) {
174                         p = bcon(!FLOAT_ISZERO(r->n_dcon));
175                         nfree(r);
176                         r = p;
177                 }
178         }
179
ragge
1.22
180         ifopty == UTYPE && l->n_op == ICON ){
ragge
1.1
181
182                 switcho ){
183
184                 case NOT:
ragge
1.94
185                 case UMINUS:
ragge
1.1
186                 case COMPL:
187                         ifconvallol ) ) return(l);
188                         break;
189                 }
ragge
1.71
190         } else if (o == NOT && l->n_op == FCON) {
ragge
1.274
191                 l = clocal(block(SCONVlNILINT00));
ragge
1.94
192         } else ifo == UMINUS && l->n_op == FCON ){
ragge
1.206
193                         l->n_dcon = FLOAT_NEG(l->n_dcon);
ragge
1.1
194                         return(l);
195
ragge
1.44
196         } else ifo==QUEST && l->n_op==ICON ) {
ragge
1.41
197                 CONSZ c = l->n_lval;
198                 nfree(l);
199                 if (c) {
ragge
1.215
200                         walkf(r->n_rightputjops0);
ragge
1.41
201                         tfree(r->n_right);
202                         l = r->n_left;
203                 } else {
ragge
1.215
204                         walkf(r->n_leftputjops0);
ragge
1.41
205                         tfree(r->n_left);
206                         l = r->n_right;
ragge
1.1
207                 }
ragge
1.214
208                 nfree(r);
209                 return(l);
ragge
1.155
210         } else ifopty == BITYPE && l->n_op == ICON && r->n_op == ICON ){
ragge
1.1
211
212                 switcho ){
213
ragge
1.159
214                 case PLUS:
215                 case MINUS:
216                 case MUL:
217                 case DIV:
218                 case MOD:
219                         /*
220                          * Do type propagation for simple types here.
221                          * The constant value is correct anyway.
222                          * Maybe this op shortcut should be removed?
223                          */
224                         if (l->n_sp == NULL && r->n_sp == NULL &&
225                             l->n_type < BTMASK && r->n_type < BTMASK) {
226                                 if (l->n_type > r->n_type)
227                                         r->n_type = l->n_type;
228                                 else
229                                         l->n_type = r->n_type;
230                         }
231                         /* FALLTHROUGH */
ragge
1.1
232                 case ULT:
233                 case UGT:
234                 case ULE:
235                 case UGE:
236                 case LT:
237                 case GT:
238                 case LE:
239                 case GE:
240                 case EQ:
ragge
1.48
241                 case NE:
ragge
1.1
242                 case ANDAND:
243                 case OROR:
244                 case AND:
245                 case OR:
246                 case ER:
247                 case LS:
248                 case RS:
ragge
1.200
249                         if (!ISPTR(l->n_type) && !ISPTR(r->n_type)) {
250                                 ifconvallor ) ) {
251                                         nfree(r);
252                                         return(l);
253                                 }
ragge
1.44
254                         }
ragge
1.1
255                         break;
256                 }
ragge
1.44
257         } else if (opty == BITYPE && (l->n_op == FCON || l->n_op == ICON) &&
258             (r->n_op == FCON || r->n_op == ICON) && (o == PLUS || o == MINUS ||
gmcgarry
1.234
259             o == MUL || o == DIV || (o >= EQ && o <= GT) )) {
ragge
1.270
260                 TWORD t;
ragge
1.261
261 #ifndef CC_DIV_0
ragge
1.257
262                 if (o == DIV &&
263                     ((r->n_op == ICON && r->n_lval == 0) ||
264                      (r->n_op == FCON && r->n_dcon == 0.0)))
265                                 goto runtime/* HW dependent */
ragge
1.261
266 #endif
gmcgarry
1.234
267                 if (l->n_op == ICON)
268                         l->n_dcon = FLOAT_CAST(l->n_lvall->n_type);
269                 if (r->n_op == ICON)
270                         r->n_dcon = FLOAT_CAST(r->n_lvalr->n_type);
ragge
1.44
271                 switch(o){
272                 case PLUS:
273                 case MINUS:
274                 case MUL:
275                 case DIV:
276                         switch (o) {
277                         case PLUS:
ragge
1.206
278                                 l->n_dcon = FLOAT_PLUS(l->n_dconr->n_dcon);
279                                 break;
ragge
1.44
280                         case MINUS:
ragge
1.206
281                                 l->n_dcon = FLOAT_MINUS(l->n_dconr->n_dcon);
282                                 break;
ragge
1.44
283                         case MUL:
ragge
1.206
284                                 l->n_dcon = FLOAT_MUL(l->n_dconr->n_dcon);
285                                 break;
ragge
1.44
286                         case DIV:
ragge
1.206
287                                 l->n_dcon = FLOAT_DIV(l->n_dconr->n_dcon);
288                                 break;
ragge
1.44
289                         }
ragge
1.270
290                         t = (l->n_type > r->n_type ? l->n_type : r->n_type);
ragge
1.44
291                         l->n_op = FCON;
ragge
1.270
292                         l->n_type = t;
ragge
1.44
293                         nfree(r);
294                         return(l);
gmcgarry
1.234
295                 case EQ:
296                 case NE:
297                 case LE:
298                 case LT:
299                 case GE:
300                 case GT:
301                         switch (o) {
302                         case EQ:
303                                 l->n_lval = FLOAT_EQ(l->n_dconr->n_dcon);
304                                 break;
305                         case NE:
306                                 l->n_lval = FLOAT_NE(l->n_dconr->n_dcon);
307                                 break;
308                         case LE:
309                                 l->n_lval = FLOAT_LE(l->n_dconr->n_dcon);
310                                 break;
311                         case LT:
312                                 l->n_lval = FLOAT_LT(l->n_dconr->n_dcon);
313                                 break;
314                         case GE:
315                                 l->n_lval = FLOAT_GE(l->n_dconr->n_dcon);
316                                 break;
317                         case GT:
318                                 l->n_lval = FLOAT_GT(l->n_dconr->n_dcon);
319                                 break;
320                         }
321                         nfree(r);
ragge
1.236
322                         r = bcon(l->n_lval);
323                         nfree(l);
324                         return r;
ragge
1.1
325                 }
ragge
1.44
326         }
ragge
1.261
327 #ifndef CC_DIV_0
otto
1.170
328 runtime:
ragge
1.261
329 #endif
ragge
1.30
330         /* its real; we must make a new node */
ragge
1.1
331
ragge
1.274
332         p = block(olrINT00);
ragge
1.1
333
334         actions = opact(p);
335
ragge
1.66
336         if (actions & LVAL) { /* check left descendent */
337                 if (notlval(p->n_left)) {
338                         uerror("lvalue required");
stefan
1.186
339                         nfree(p);
340                         return l;
ragge
1.68
341 #ifdef notyet
ragge
1.67
342                 } else {
343                         if ((l->n_type > BTMASK && ISCON(l->n_qual)) ||
344                             (l->n_type <= BTMASK && ISCON(l->n_qual << TSHIFT)))
345                                 if (blevel > 0)
346                                         uerror("lvalue is declared const");
ragge
1.68
347 #endif
ragge
1.67
348                 }
ragge
1.66
349         }
ragge
1.1
350
351         ifactions & NCVTR ){
ragge
1.22
352                 p->n_left = pconvertp->n_left );
ragge
1.1
353                 }
354         else if( !(actions & NCVT ) ){
355                 switchopty ){
356
357                 case BITYPE:
ragge
1.22
358                         p->n_right = pconvertp->n_right );
ragge
1.1
359                 case UTYPE:
ragge
1.22
360                         p->n_left = pconvertp->n_left );
ragge
1.1
361
362                         }
363                 }
364
ragge
1.64
365         if ((actions&PUN) && (o!=CAST))
ragge
1.1
366                 chkpun(p);
367
368         ifactions & (TYPL|TYPR) ){
369
ragge
1.22
370                 q = (actions&TYPL) ? p->n_left : p->n_right;
ragge
1.1
371
ragge
1.22
372                 p->n_type = q->n_type;
ragge
1.66
373                 p->n_qual = q->n_qual;
ragge
1.29
374                 p->n_df = q->n_df;
ragge
1.252
375                 p->n_ap = q->n_ap;
ragge
1.1
376                 }
377
378         ifactions & CVTL ) p = convertpCVTL );
379         ifactions & CVTR ) p = convertpCVTR );
380         ifactions & TYMATCH ) p = tymatch(p);
381         ifactions & PTMATCH ) p = ptmatch(p);
382
383         ifactions & OTHER ){
ragge
1.252
384                 struct symtab *sp1;
ragge
1.225
385
ragge
1.22
386                 l = p->n_left;
387                 r = p->n_right;
ragge
1.1
388
389                 switch(o){
390
391                 case NAME:
ragge
1.203
392                         cerror("buildtree NAME");
ragge
1.1
393
394                 case STREF:
395                         /* p->x turned into *(p+offset) */
396                         /* rhs must be a name; check correctness */
397
ragge
1.23
398                         /* Find member symbol struct */
399                         if (l->n_type != PTR+STRTY && l->n_type != PTR+UNIONTY){
400                                 uerror("struct or union required");
401                                 break;
402                         }
403
ragge
1.252
404                         if ((sp1 = strmemb(l->n_ap)) == NULL) {
ragge
1.23
405                                 uerror("undefined struct or union");
stefan
1.190
406                                 break;
407                         }
ragge
1.23
408
ragge
1.252
409                         if ((sp = findmember(sp1r->n_name)) == NULL) {
ragge
1.218
410                                 uerror("member '%s' not declared"r->n_name);
stefan
1.190
411                                 break;
412                         }
ragge
1.23
413
414                         r->n_sp = sp;
415                         p = stref(p);
416                         break;
417
ragge
1.94
418                 case UMUL:
ragge
1.93
419                         if (l->n_op == ADDROF) {
ragge
1.41
420                                 nfree(p);
ragge
1.22
421                                 p = l->n_left;
ragge
1.41
422                                 nfree(l);
423                         }
ragge
1.22
424                         if( !ISPTR(l->n_type))uerror("illegal indirection");
425                         p->n_type = DECREF(l->n_type);
ragge
1.67
426                         p->n_qual = DECREF(l->n_qual);
ragge
1.29
427                         p->n_df = l->n_df;
ragge
1.252
428                         p->n_ap = l->n_ap;
ragge
1.1
429                         break;
430
ragge
1.93
431                 case ADDROF:
ragge
1.22
432                         switchl->n_op ){
ragge
1.1
433
ragge
1.94
434                         case UMUL:
ragge
1.41
435                                 nfree(p);
ragge
1.22
436                                 p = l->n_left;
ragge
1.41
437                                 nfree(l);
ragge
1.130
438                         case TEMP:
ragge
1.1
439                         case NAME:
ragge
1.68
440                                 p->n_type = INCREF(l->n_type);
441                                 p->n_qual = INCQAL(l->n_qual);
ragge
1.29
442                                 p->n_df = l->n_df;
ragge
1.252
443                                 p->n_ap = l->n_ap;
ragge
1.1
444                                 break;
445
446                         case COMOP:
ragge
1.41
447                                 nfree(p);
ragge
1.93
448                                 lr = buildtree(ADDROFl->n_rightNIL);
ragge
1.22
449                                 p = buildtreeCOMOPl->n_leftlr );
ragge
1.41
450                                 nfree(l);
ragge
1.1
451                                 break;
452
453                         case QUEST:
ragge
1.93
454                                 lr = buildtreeADDROFl->n_right->n_rightNIL );
455                                 ll = buildtreeADDROFl->n_right->n_leftNIL );
ragge
1.41
456                                 nfree(p); nfree(l->n_right);
ragge
1.22
457                                 p = buildtreeQUESTl->n_leftbuildtreeCOLONlllr ) );
ragge
1.41
458                                 nfree(l);
ragge
1.1
459                                 break;
460
461                         default:
ragge
1.22
462                                 uerror("unacceptable operand of &: %d"l->n_op );
ragge
1.1
463                                 break;
464                                 }
465                         break;
466
467                 case LS:
ragge
1.150
468                 case RS/* must make type size at least int... */
469                         if (p->n_type == CHAR || p->n_type == SHORT) {
ragge
1.274
470                                 p->n_left = makety(lINT000);
ragge
1.150
471                         } else if (p->n_type == UCHAR || p->n_type == USHORT) {
ragge
1.274
472                                 p->n_left = makety(lUNSIGNED000);
ragge
1.150
473                         }
474                         l = p->n_left;
475                         p->n_type = l->n_type;
476                         p->n_qual = l->n_qual;
477                         p->n_df = l->n_df;
ragge
1.252
478                         p->n_ap = l->n_ap;
ragge
1.150
479
480                         /* FALLTHROUGH */
ragge
1.95
481                 case LSEQ:
ragge
1.150
482                 case RSEQ/* ...but not for assigned types */
ragge
1.252
483                         if(tsize(r->n_typer->n_dfr->n_ap) > SZINT)
ragge
1.274
484                                 p->n_right = makety(rINT000);
ragge
1.1
485                         break;
486
487                 case RETURN:
488                 case ASSIGN:
489                 case CAST:
490                         /* structure assignment */
491                         /* take the addresses of the two sides; then make an
ragge
1.2
492                          * operator using STASG and
493                          * the addresses of left and right */
ragge
1.1
494
ragge
1.252
495                         if (strmemb(l->n_ap) != strmemb(r->n_ap))
496                                 uerror("assignment of different structures");
497
498                         r = buildtree(ADDROFrNIL);
499
500                         l = block(STASGlrr->n_typer->n_dfr->n_ap);
501                         l = clocal(l);
ragge
1.1
502
ragge
1.252
503                         ifo == RETURN ){
504                                 nfree(p);
505                                 p = l;
ragge
1.1
506                                 break;
ragge
1.252
507                         }
508
509                         p->n_op = UMUL;
510                         p->n_left = l;
511                         p->n_right = NIL;
512                         break;
513
ragge
1.266
514                 case QUEST/* fixup types of : */
515                         if (r->n_left->n_type != p->n_type)
516                                 r->n_left = makety(r->n_leftp->n_type,
517                                     p->n_qualp->n_dfp->n_ap);
518                         if (r->n_right->n_type != p->n_type)
519                                 r->n_right = makety(r->n_rightp->n_type,
520                                     p->n_qualp->n_dfp->n_ap);
521                         break;
522
ragge
1.1
523                 case COLON:
524                         /* structure colon */
525
ragge
1.252
526                         if (strmemb(l->n_ap) != strmemb(r->n_ap))
ragge
1.26
527                                 uerror"type clash in conditional" );
ragge
1.1
528                         break;
529
530                 case CALL:
ragge
1.45
531                         p->n_right = r = strargs(p->n_right);
ragge
1.171
532                         p = funcode(p);
533                         /* FALLTHROUGH */
ragge
1.95
534                 case UCALL:
ragge
1.23
535                         if (!ISPTR(l->n_type))
536                                 uerror("illegal function");
ragge
1.22
537                         p->n_type = DECREF(l->n_type);
ragge
1.23
538                         if (!ISFTN(p->n_type))
539                                 uerror("illegal function");
540                         p->n_type = DECREF(p->n_type);
ragge
1.252
541                         p->n_df = l->n_df+1/* add one for prototypes */
542                         p->n_ap = l->n_ap;
ragge
1.23
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.252
594                         if ((sp2 = findmember(strmemb(sp->sap), s))) {
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  */
ragge
1.269
611 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
ragge
1.252
627         p = block(NAMENILNILsp->stypesp->sdfsp->sap);
ragge
1.199
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         }
648 #endif
649         if (sp->stype == UNDEF) {
650                 uerror("%s undefined"sp->sname);
651                 /* make p look reasonable */
652                 p->n_type = INT;
653                 p->n_df = NULL;
654                 defid(pSNULL);
655         }
656         if (sp->sclass == MOE) {
657                 p->n_op = ICON;
658                 p->n_lval = sp->soffset;
659                 p->n_df = NULL;
660                 p->n_sp = NULL;
661         }
662         return clocal(p);
663 }
664
665 /*
ragge
1.241
666  * Cast a node to another type by inserting a cast.
ragge
1.240
667  * Just a nicer interface to buildtree.
668  * Returns the new tree.
669  */
670 NODE *
671 cast(NODE *pTWORD tTWORD u)
672 {
673         NODE *q;
674
ragge
1.274
675         q = block(NAMENILNILt00);
ragge
1.240
676         q->n_qual = u;
677         q = buildtree(CASTqp);
678         p = q->n_right;
679         nfree(q->n_left);
680         nfree(q);
681         return p;
682 }
683
684 /*
ragge
1.241
685  * Cast and complain if necessary by not inserining a cast.
686  */
687 NODE *
ragge
1.252
688 ccast(NODE *pTWORD tTWORD uunion dimfun *dfstruct attr *ap)
ragge
1.241
689 {
690         NODE *q;
691
692         /* let buildtree do typechecking (and casting) */ 
ragge
1.252
693         q = block(NAMENILNILtdfap);
ragge
1.241
694         p = buildtree(ASSIGNqp);
695         nfree(p->n_left);
696         q = optim(p->n_right);
697         nfree(p);
698         return q;
699 }
700
701 /*
ragge
1.107
702  * Do a conditional branch.
703  */
704 void
705 cbranch(NODE *pNODE *q)
706 {
707         p = buildtree(CBRANCHpq);
708         if (p->n_left->n_op == ICON) {
ragge
1.208
709                 if (p->n_left->n_lval != 0) {
ragge
1.107
710                         branch(q->n_lval); /* branch always */
ragge
1.208
711                         reached = 0;
712                 }
ragge
1.107
713                 tfree(p);
714                 tfree(q);
715                 return;
716         }
717         ecomp(p);
718 }
719
ragge
1.1
720 NODE *
ragge
1.45
721 strargsp ) register NODE *p;  { /* rewrite structure flavored arguments */
ragge
1.1
722
ragge
1.45
723         ifp->n_op == CM ){
724                 p->n_left = strargsp->n_left );
725                 p->n_right = strargsp->n_right );
ragge
1.1
726                 returnp );
727                 }
728
ragge
1.22
729         ifp->n_type == STRTY || p->n_type == UNIONTY ){
ragge
1.252
730                 p = block(STARGpNILp->n_typep->n_dfp->n_ap);
ragge
1.93
731                 p->n_left = buildtreeADDROFp->n_leftNIL );
ragge
1.1
732                 p = clocal(p);
733                 }
734         returnp );
ragge
1.2
735 }
ragge
1.1
736
ragge
1.2
737 /*
738  * apply the op o to the lval part of p; if binary, rhs is val
739  */
740 int
741 conval(NODE *pint oNODE *q)
742 {
ragge
1.264
743         TWORD tl = p->n_typetr = q->n_typetd;
ragge
1.1
744         int iu;
745         CONSZ val;
ragge
1.159
746         U_CONSZ v1v2;
ragge
1.1
747
ragge
1.22
748         val = q->n_lval;
ragge
1.264
749
750         /* make both sides same type */
ragge
1.273
751         if (tl < BTMASK && tr < BTMASK) {
ragge
1.264
752                 td = tl > tr ? tl : tr;
753                 if (td < INT)
754                         td = INT;
755                 u = ISUNSIGNED(td);
756                 if (tl != td)
ragge
1.274
757                         p = makety(ptd000);
ragge
1.264
758                 if (tr != td)
ragge
1.274
759                         q = makety(qtd000);
ragge
1.264
760         } else
761                 u = ISUNSIGNED(tl) || ISUNSIGNED(tr);
ragge
1.1
762         ifu && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE);
763
ragge
1.23
764         if (p->n_sp != NULL && q->n_sp != NULL)
765                 return(0);
766         if (q->n_sp != NULL && o != PLUS)
767                 return(0);
768         if (p->n_sp != NULL && o != PLUS && o != MINUS)
769                 return(0);
ragge
1.264
770
ragge
1.161
771         v1 = p->n_lval;
772         v2 = q->n_lval;
ragge
1.1
773         switcho ){
774
775         case PLUS:
ragge
1.22
776                 p->n_lval += val;
ragge
1.23
777                 if (p->n_sp == NULL) {
ragge
1.237
778                         p->n_right = q->n_right;
ragge
1.22
779                         p->n_type = q->n_type;
ragge
1.23
780                 }
ragge
1.1
781                 break;
782         case MINUS:
ragge
1.22
783                 p->n_lval -= val;
ragge
1.1
784                 break;
785         case MUL:
ragge
1.22
786                 p->n_lval *= val;
ragge
1.1
787                 break;
788         case DIV:
ragge
1.46
789                 if (val == 0)
790                         uerror("division by 0");
ragge
1.159
791                 else  {
792                         if (u) {
793                                 v1 /= v2;
794                                 p->n_lval = v1;
795                         } else
796                                 p->n_lval /= val;
797                 }
ragge
1.1
798                 break;
799         case MOD:
ragge
1.46
800                 if (val == 0)
801                         uerror("division by 0");
ragge
1.159
802                 else  {
803                         if (u) {
804                                 v1 %= v2;
805                                 p->n_lval = v1;
806                         } else
807                                 p->n_lval %= val;
808                 }
ragge
1.1
809                 break;
810         case AND:
ragge
1.22
811                 p->n_lval &= val;
ragge
1.1
812                 break;
813         case OR:
ragge
1.22
814                 p->n_lval |= val;
ragge
1.1
815                 break;
816         case ER:
ragge
1.22
817                 p->n_lval ^= val;
ragge
1.1
818                 break;
819         case LS:
gmcgarry
1.238
820                 i = (int)val;
ragge
1.22
821                 p->n_lval = p->n_lval << i;
ragge
1.1
822                 break;
823         case RS:
gmcgarry
1.238
824                 i = (int)val;
ragge
1.159
825                 if (u) {
826                         v1 = v1 >> i;
827                         p->n_lval = v1;
828                 } else
829                         p->n_lval = p->n_lval >> i;
ragge
1.1
830                 break;
831
ragge
1.94
832         case UMINUS:
ragge
1.22
833                 p->n_lval = - p->n_lval;
ragge
1.1
834                 break;
835         case COMPL:
ragge
1.22
836                 p->n_lval = ~p->n_lval;
ragge
1.1
837                 break;
838         case NOT:
ragge
1.22
839                 p->n_lval = !p->n_lval;
ragge
1.1
840                 break;
841         case LT:
ragge
1.22
842                 p->n_lval = p->n_lval < val;
ragge
1.1
843                 break;
844         case LE:
ragge
1.22
845                 p->n_lval = p->n_lval <= val;
ragge
1.1
846                 break;
847         case GT:
ragge
1.22
848                 p->n_lval = p->n_lval > val;
ragge
1.1
849                 break;
850         case GE:
ragge
1.22
851                 p->n_lval = p->n_lval >= val;
ragge
1.1
852                 break;
853         case ULT:
ragge
1.159
854                 p->n_lval = v1 < v2;
ragge
1.1
855                 break;
856         case ULE:
ragge
1.159
857                 p->n_lval = v1 <= v2;
ragge
1.1
858                 break;
859         case UGT:
ragge
1.159
860                 p->n_lval = v1 > v2;
ragge
1.1
861                 break;
862         case UGE:
ragge
1.159
863                 p->n_lval = v1 >= v2;
ragge
1.1
864                 break;
865         case EQ:
ragge
1.22
866                 p->n_lval = p->n_lval == val;
ragge
1.1
867                 break;
868         case NE:
ragge
1.22
869                 p->n_lval = p->n_lval != val;
ragge
1.1
870                 break;
ragge
1.155
871         case ANDAND:
872                 p->n_lval = p->n_lval && val;
873                 break;
ragge
1.154
874         case OROR:
875                 p->n_lval = p->n_lval || val;
876                 break;
ragge
1.1
877         default:
878                 return(0);
879                 }
ragge
1.249
880         /* Do the best in making everything type correct after calc */
ragge
1.250
881         if (p->n_sp == NULL && q->n_sp == NULL)
882                 p->n_lval = valcast(p->n_lvalp->n_type);
ragge
1.1
883         return(1);
884