Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20110122220823

Diff

Diff from 1.268 to:

Annotations

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

Annotated File View

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