Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20100812063922

Diff

Diff from 1.253 to:

Annotations

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

Annotated File View

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