Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20110126122522

Diff

Diff from 1.270 to:

Annotations

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

Annotated File View

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