Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20100905102010

Diff

Diff from 1.257 to:

Annotations

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

Annotated File View

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