Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20140919174445

Diff

Diff from 1.14 to:

Annotations

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

Annotated File View

plunky
1.14
1 /*      $Id: trees.c,v 1.14 2014/09/19 17:44:46 plunky Exp $    */
ragge
1.1
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.
66  * - Convert some C-specific ops into branches.
67  */
68
69 # include "pass1.h"
70 # include "pass2.h"
71
72 # include <stdarg.h>
73 # include <string.h>
74
75 static void chkpun(NODE *p);
76 static int opact(NODE *p);
77 static int moditype(TWORD);
78 static NODE *strargs(NODE *);
79 static void rmcops(NODE *p);
80 static NODE *tymatch(NODE *p);
81 void putjops(NODE *, void *);
82 static struct symtab *findmember(struct symtab *, char *);
83 int inftn/* currently between epilog/prolog */
84
85 static char *tnames[] = {
86         "undef",
87         "farg",
88         "char",
89         "unsigned char",
90         "short",
91         "unsigned short",
92         "int",
93         "unsigned int",
94         "long",
95         "unsigned long",
96         "long long",
97         "unsigned long long",
98         "float",
99         "double",
100         "long double",
101         "strty",
102         "unionty",
103         "enumty",
104         "moety",
105         "void",
106         "signed"/* pass1 */
107         "bool"/* pass1 */
108         "fimag"/* pass1 */
109         "dimag"/* pass1 */
110         "limag"/* pass1 */
111         "fcomplex"/* pass1 */
112         "dcomplex"/* pass1 */
113         "lcomplex"/* pass1 */
114         "enumty"/* pass1 */
115         "?""?"
116 };
117
118 /*      some special actions, used in finding the type of nodes */
119 # define NCVT 01
120 # define PUN 02
121 # define TYPL 04
122 # define TYPR 010
123 # define TYMATCH 040
124 # define LVAL 0100
125 # define CVTO 0200
126 # define CVTL 0400
127 # define CVTR 01000
128 # define PTMATCH 02000
129 # define OTHER 04000
130 # define NCVTR 010000
131 # define PROML 020000   /* promote left operand */
132
133 /* node conventions:
134
135         NAME:   rval>0 is stab index for external
136                 rval<0 is -inlabel number
137                 lval is offset in bits
138         ICON:   lval has the value
139                 rval has the STAB index, or - label number,
140                         if a name whose address is in the constant
141                 rval = NONAME means no name
142         REG:    rval is reg. identification cookie
143
144         */
145
146 extern int negrel[];
147
148 /* Have some defaults for most common targets */
149 #ifndef WORD_ADDRESSED
150 #define offcon(o,t,d,ap) xbcon((o/SZCHAR), NULL, INTPTR)
151 #define VBLOCK(p,b,t,d,a) buildtree(DIV, p, b)
152 #define MBLOCK(p,b,t,d,a) buildtree(MUL, p, b)
153 #else
154 #define VBLOCK(p,b,t,d,a) block(PVCONV, p, b, t, d, a)
155 #define MBLOCK(p,b,t,d,a) block(PMCONV, p, b, t, d, a)
156 #endif
157
158 NODE *
159 buildtree(int oNODE *lNODE *r)
160 {
161         NODE *p, *q;
162         int actions;
163         int optyn;
164         struct symtab *sp = NULL/* XXX gcc */
165         NODE *lr, *ll;
166
167 #ifdef PCC_DEBUG
168         if (bdebug) {
169                 printf("buildtree(%s, %p, %p)\n"copst(o), lr);
170                 if (lfwalk(leprint0);
171                 if (rfwalk(reprint0);
172         }
173 #endif
174         opty = coptype(o);
175
176         /* check for constants */
177
178         if (o == ANDAND || o == OROR || o == NOT) {
179                 if (l->n_op == FCON) {
180                         p = bcon(!FLOAT_ISZERO(l->n_dcon));
181                         nfree(l);
182                         l = p;
183                 }
184                 if (o != NOT && r->n_op == FCON) {
185                         p = bcon(!FLOAT_ISZERO(r->n_dcon));
186                         nfree(r);
187                         r = p;
188                 }
189         }
190
191         ifopty == UTYPE && l->n_op == ICON ){
192
193                 switcho ){
194
195                 case NOT:
196                 case UMINUS:
197                 case COMPL:
198                         ifconvallol ) ) return(l);
199                         break;
200                 }
201         } else if (o == NOT && l->n_op == FCON) {
202                 l = clocal(block(SCONVlNILINT00));
203         } else ifo == UMINUS && l->n_op == FCON ){
204                         l->n_dcon = FLOAT_NEG(l->n_dcon);
205                         return(l);
206
207         } else ifo==QUEST &&
208             (l->n_op==ICON || (l->n_op==NAME && ISARY(l->n_type)))) {
209                 CONSZ c = l->n_lval;
210                 if (l->n_op==NAME)
211                         c = 1/* will become constant later */
212                 nfree(l);
213                 if (c) {
214                         walkf(r->n_rightputjops0);
215                         tfree(r->n_right);
216                         l = r->n_left;
217                 } else {
218                         walkf(r->n_leftputjops0);
219                         tfree(r->n_left);
220                         l = r->n_right;
221                 }
222                 nfree(r);
223                 return(l);
224         } else ifopty == BITYPE && l->n_op == ICON && r->n_op == ICON ){
225
226                 switcho ){
227
228                 case PLUS:
229                 case MINUS:
230                 case MUL:
231                 case DIV:
232                 case MOD:
233                         /*
234                          * Do type propagation for simple types here.
235                          * The constant value is correct anyway.
236                          * Maybe this op shortcut should be removed?
237                          */
238                         if (l->n_sp == NULL && r->n_sp == NULL &&
239                             l->n_type < BTMASK && r->n_type < BTMASK) {
240                                 if (l->n_type > r->n_type)
241                                         r->n_type = l->n_type;
242                                 else
243                                         l->n_type = r->n_type;
244                         }
245                         /* FALLTHROUGH */
246                 case ULT:
247                 case UGT:
248                 case ULE:
249                 case UGE:
250                 case LT:
251                 case GT:
252                 case LE:
253                 case GE:
254                 case EQ:
255                 case NE:
256                 case ANDAND:
257                 case OROR:
258                 case AND:
259                 case OR:
260                 case ER:
261                 case LS:
262                 case RS:
263                         if (!ISPTR(l->n_type) && !ISPTR(r->n_type)) {
264                                 ifconvallor ) ) {
265                                         nfree(r);
266                                         return(l);
267                                 }
268                         }
269                         break;
270                 }
271         } else if (opty == BITYPE && (l->n_op == FCON || l->n_op == ICON) &&
272             (r->n_op == FCON || r->n_op == ICON) && (o == PLUS || o == MINUS ||
273             o == MUL || o == DIV || (o >= EQ && o <= GT) )) {
274                 TWORD t;
275 #ifndef CC_DIV_0
276                 if (o == DIV &&
277                     ((r->n_op == ICON && r->n_lval == 0) ||
278                      (r->n_op == FCON && r->n_dcon == 0.0)))
279                                 goto runtime/* HW dependent */
280 #endif
281                 if (l->n_op == ICON)
282                         l->n_dcon = FLOAT_CAST(l->n_lvall->n_type);
283                 if (r->n_op == ICON)
284                         r->n_dcon = FLOAT_CAST(r->n_lvalr->n_type);
285                 switch(o){
286                 case PLUS:
287                 case MINUS:
288                 case MUL:
289                 case DIV:
290                         switch (o) {
291                         case PLUS:
292                                 l->n_dcon = FLOAT_PLUS(l->n_dconr->n_dcon);
293                                 break;
294                         case MINUS:
295                                 l->n_dcon = FLOAT_MINUS(l->n_dconr->n_dcon);
296                                 break;
297                         case MUL:
298                                 l->n_dcon = FLOAT_MUL(l->n_dconr->n_dcon);
299                                 break;
300                         case DIV:
301                                 l->n_dcon = FLOAT_DIV(l->n_dconr->n_dcon);
302                                 break;
303                         }
304                         t = (l->n_type > r->n_type ? l->n_type : r->n_type);
305                         l->n_op = FCON;
306                         l->n_type = t;
307                         nfree(r);
308                         return(l);
309                 case EQ:
310                 case NE:
311                 case LE:
312                 case LT:
313                 case GE:
314                 case GT:
315                         switch (o) {
316                         case EQ:
317                                 n = FLOAT_EQ(l->n_dconr->n_dcon);
318                                 break;
319                         case NE:
320                                 n = FLOAT_NE(l->n_dconr->n_dcon);
321                                 break;
322                         case LE:
323                                 n = FLOAT_LE(l->n_dconr->n_dcon);
324                                 break;
325                         case LT:
326                                 n = FLOAT_LT(l->n_dconr->n_dcon);
327                                 break;
328                         case GE:
329                                 n = FLOAT_GE(l->n_dconr->n_dcon);
330                                 break;
331                         case GT:
332                                 n = FLOAT_GT(l->n_dconr->n_dcon);
333                                 break;
334                         default:
335                                 n = 0/* XXX flow analysis */
336                         }
337                         nfree(r);
338                         nfree(l);
339                         return bcon(n);
340                 }
341         }
342 #ifndef CC_DIV_0
343 runtime:
344 #endif
345         /* its real; we must make a new node */
346
347         p = block(olrINT00);
348
349         actions = opact(p);
350
351         if (actions & PROML)
352                 p->n_left = intprom(p->n_left);
353
354         if (actions & LVAL) { /* check left descendent */
355                 if (notlval(p->n_left)) {
356                         uerror("lvalue required");
357                         nfree(p);
358                         return l;
359 #ifdef notyet
360                 } else {
361                         if ((l->n_type > BTMASK && ISCON(l->n_qual)) ||
362                             (l->n_type <= BTMASK && ISCON(l->n_qual << TSHIFT)))
363                                 if (blevel > 0)
364                                         uerror("lvalue is declared const");
365 #endif
366                 }
367         }
368
369         ifactions & NCVTR ){
370                 p->n_left = pconvertp->n_left );
371                 }
372         else if( !(actions & NCVT ) ){
373                 switchopty ){
374
375                 case BITYPE:
376                         p->n_right = pconvertp->n_right );
plunky
1.7
377                         /* FALLTHROUGH */
ragge
1.1
378                 case UTYPE:
379                         p->n_left = pconvertp->n_left );
380
381                         }
382                 }
383
384         if ((actions&PUN) && (o!=CAST))
385                 chkpun(p);
386
387         ifactions & (TYPL|TYPR) ){
388
389                 q = (actions&TYPL) ? p->n_left : p->n_right;
390
391                 p->n_type = q->n_type;
392                 p->n_qual = q->n_qual;
393                 p->n_df = q->n_df;
394                 p->n_ap = q->n_ap;
395                 }
396
397         ifactions & CVTL ) p = convertpCVTL );
398         ifactions & CVTR ) p = convertpCVTR );
399         ifactions & TYMATCH ) p = tymatch(p);
400         ifactions & PTMATCH ) p = ptmatch(p);
401
402         ifactions & OTHER ){
403                 struct symtab *sp1;
404
405                 l = p->n_left;
406                 r = p->n_right;
407
408                 switch(o){
409
410                 case NAME:
411                         cerror("buildtree NAME");
412
413                 case STREF:
414                         /* p->x turned into *(p+offset) */
415                         /* rhs must be a name; check correctness */
416
417                         /* Find member symbol struct */
418                         if (l->n_type != PTR+STRTY && l->n_type != PTR+UNIONTY){
419                                 uerror("struct or union required");
420                                 break;
421                         }
422
423                         if ((sp1 = strmemb(l->n_ap)) == NULL) {
424                                 uerror("undefined struct or union");
425                                 break;
426                         }
427
428                         if ((sp = findmember(sp1r->n_name)) == NULL) {
429                                 uerror("member '%s' not declared"r->n_name);
430                                 break;
431                         }
432
433                         r->n_sp = sp;
434                         p = stref(p);
435                         break;
436
437                 case UMUL:
438                         if (l->n_op == ADDROF) {
439                                 nfree(p);
440                                 p = nfree(l);
441                         }
442                         if( !ISPTR(l->n_type))uerror("illegal indirection");
443                         p->n_type = DECREF(l->n_type);
444                         p->n_qual = DECREF(l->n_qual);
445                         p->n_df = l->n_df;
446                         p->n_ap = l->n_ap;
447                         break;
448
449                 case ADDROF:
450                         switchl->n_op ){
451
452                         case UMUL:
453                                 nfree(p);
454                                 p = nfree(l);
455                                 /* FALLTHROUGH */
456                         case TEMP:
457                         case NAME:
458                                 p->n_type = INCREF(l->n_type);
459                                 p->n_qual = INCQAL(l->n_qual);
460                                 p->n_df = l->n_df;
461                                 p->n_ap = l->n_ap;
462                                 break;
463
464                         case COMOP:
465                                 nfree(p);
466                                 lr = buildtree(ADDROFl->n_rightNIL);
467                                 p = buildtreeCOMOPl->n_leftlr );
468                                 nfree(l);
469                                 break;
470
471                         case QUEST:
472                                 lr = buildtreeADDROFl->n_right->n_rightNIL );
473                                 ll = buildtreeADDROFl->n_right->n_leftNIL );
474                                 nfree(p); nfree(l->n_right);
475                                 p = buildtreeQUESTl->n_leftbuildtreeCOLONlllr ) );
476                                 nfree(l);
477                                 break;
478
479                         default:
480                                 uerror("unacceptable operand of &: %d"l->n_op );
481                                 break;
482                                 }
483                         break;
484
485                 case LS:
486                 case RS/* must make type size at least int... */
487                         if (p->n_type == CHAR || p->n_type == SHORT) {
488                                 p->n_left = makety(lINT000);
489                         } else if (p->n_type == UCHAR || p->n_type == USHORT) {
490                                 p->n_left = makety(lUNSIGNED000);
491                         }
492                         l = p->n_left;
493                         p->n_type = l->n_type;
494                         p->n_qual = l->n_qual;
495                         p->n_df = l->n_df;
496                         p->n_ap = l->n_ap;
497
498                         /* FALLTHROUGH */
499                 case LSEQ:
500                 case RSEQ/* ...but not for assigned types */
501                         if(tsize(r->n_typer->n_dfr->n_ap) > SZINT)
502                                 p->n_right = makety(rINT000);
503                         break;
504
505                 case RETURN:
506                 case ASSIGN:
507                 case CAST:
508                         /* structure assignment */
509                         /* take the addresses of the two sides; then make an
510                          * operator using STASG and
511                          * the addresses of left and right */
512
513                         if (strmemb(l->n_ap) != strmemb(r->n_ap))
514                                 uerror("assignment of different structures");
515
516                         r = buildtree(ADDROFrNIL);
517
518                         l = block(STASGlrr->n_typer->n_dfr->n_ap);
519                         l = clocal(l);
520
521                         ifo == RETURN ){
522                                 nfree(p);
523                                 p = l;
524                                 break;
525                         }
526
527                         p->n_op = UMUL;
528                         p->n_left = l;
529                         p->n_right = NIL;
530                         break;
531
532                 case QUEST/* fixup types of : */
533                         if (r->n_left->n_type != p->n_type)
534                                 r->n_left = makety(r->n_leftp->n_type,
535                                     p->n_qualp->n_dfp->n_ap);
536                         if (r->n_right->n_type != p->n_type)
537                                 r->n_right = makety(r->n_rightp->n_type,
538                                     p->n_qualp->n_dfp->n_ap);
539                         break;
540
541                 case COLON:
542                         /* structure colon */
543
544                         if (strmemb(l->n_ap) != strmemb(r->n_ap))
545                                 uerror"type clash in conditional" );
546                         break;
547
548                 case CALL:
549                         p->n_right = r = strargs(p->n_right);
550                         p = funcode(p);
551                         /* FALLTHROUGH */
552                 case UCALL:
553                         if (!ISPTR(l->n_type))
554                                 uerror("illegal function");
555                         p->n_type = DECREF(l->n_type);
556                         if (!ISFTN(p->n_type))
557                                 uerror("illegal function");
558                         p->n_type = DECREF(p->n_type);
559                         p->n_df = l->n_df+1/* add one for prototypes */
560                         p->n_ap = l->n_ap;
561                         if (p->n_type == STRTY || p->n_type == UNIONTY) {
562                                 /* function returning structure */
563                                 /*  make function really return ptr to str., with * */
564
565                                 p->n_op += STCALL-CALL;
566                                 p->n_type = INCREF(p->n_type);
567                                 p = clocal(p); /* before recursing */
568                                 p = buildtree(UMULpNIL);
569
570                                 }
571                         break;
572
573                 default:
574                         cerror"other code %d"o );
575                         }
576
577                 }
578
579         /*
580          * Allow (void)0 casts.
581          * XXX - anything on the right side must be possible to cast.
582          * XXX - remove void types further on.
583          */
584         if (p->n_op == CAST && p->n_type == VOID &&
585             p->n_right->n_op == ICON)
586                 p->n_right->n_type = VOID;
587
588         if (actions & CVTO)
589                 p = oconvert(p);
590         p = clocal(p);
591
592 #ifdef PCC_DEBUG
593         if (bdebug) {
594                 printf("End of buildtree:\n");
595                 fwalk(peprint0);
596         }
597 #endif
598
599         return(p);
600
601         }
602
603 /* Find a member in a struct or union.  May be an unnamed member */
604 static struct symtab *
605 findmember(struct symtab *spchar *s)
606 {
607         struct symtab *sp2, *sp3;
608
609         for (; sp != NULLsp = sp->snext) {
610                 if (sp->sname[0] == '*') {
611                         /* unnamed member, recurse down */
612                         if ((sp2 = findmember(strmemb(sp->sap), s))) {
613                                 sp3 = tmpalloc(sizeof (struct symtab));
614                                 *sp3 = *sp2;
615                                 sp3->soffset += sp->soffset;
616                                 return sp3;
617                         }
618                 } else if (sp->sname == s)
619                         return sp;
620         }
621         return NULL;
622 }
623
624
625 /*
626  * Check if there will be a lost label destination inside of a ?:
627  * It cannot be reached so just print it out.
628  */
629 void
630 putjops(NODE *pvoid *arg)
631 {
632         if (p->n_op == COMOP && p->n_left->n_op == GOTO)
633                 plabel((int)p->n_left->n_left->n_lval+1);
634 }
635
636 /*
637  * Build a name node based on a symtab entry.
638  * broken out from buildtree().
639  */
640 NODE *
641 nametree(struct symtab *sp)
642 {
643         NODE *p;
644
645         p = block(NAMENILNILsp->stypesp->sdfsp->sap);
646         p->n_qual = sp->squal;
647         p->n_sp = sp;
648
649 #ifndef NO_C_BUILTINS
650         if (sp->sname[0] == '_' && strncmp(sp->sname"__builtin_"10) == 0)
651                 return p;  /* do not touch builtins here */
652         
653 #endif
654
655         if (sp->sflags & STNODE) {
656                 /* Generated for optimizer */
657                 p->n_op = TEMP;
658                 p->n_rval = sp->soffset;
659         }
660
661 #ifdef GCC_COMPAT
662         /* Get a label name */
663         if (sp->sflags == SLBLNAME) {
664                 p->n_type = VOID;
665         }
666 #endif
667         if (sp->stype == UNDEF) {
668                 uerror("%s undefined"sp->sname);
669                 /* make p look reasonable */
670                 p->n_type = INT;
671                 p->n_df = NULL;
672                 defid(pSNULL);
673         }
674         if (sp->sclass == MOE) {
675                 p->n_op = ICON;
676                 p->n_lval = sp->soffset;
677                 p->n_df = NULL;
678                 p->n_sp = NULL;
679         }
680         return clocal(p);
681 }
682
683 /*
684  * Cast a node to another type by inserting a cast.
685  * Just a nicer interface to buildtree.
686  * Returns the new tree.
687  */
688 NODE *
689 cast(NODE *pTWORD tTWORD u)
690 {
691         NODE *q;
692
693         q = block(NAMENILNILt00);
694         q->n_qual = u;
695         q = buildtree(CASTqp);
696         p = q->n_right;
697         nfree(q->n_left);
698         nfree(q);
699         return p;
700 }
701
702 /*
703  * Cast and complain if necessary by not inserining a cast.
704  */
705 NODE *
706 ccast(NODE *pTWORD tTWORD uunion dimfun *dfstruct attr *ap)
707 {
708         NODE *q;
709
710         /* let buildtree do typechecking (and casting) */ 
711         q = block(NAMENILNILtdfap);
712         p = buildtree(ASSIGNqp);
713         nfree(p->n_left);
714         q = optim(p->n_right);
715         nfree(p);
716         return q;
717 }
718
719 /*
720  * Do an actual cast of a constant (if possible).
721  * Routine assumes 2-complement (is there anything else today?)
722  * Returns 1 if handled, 0 otherwise.
723  */
724 int
725 concast(NODE *pTWORD t)
726 {
727         extern short sztable[];
728         CONSZ val;
729
730         if (p->n_op != ICON && p->n_op != FCON/* only constants */
731                 return 0;
732         if (p->n_op == ICON && p->n_sp != NULL) { /* no addresses */
733                 if (t == BOOL) {
734                         p->n_lval = 1p->n_type = BOOLp->n_sp = NULL;
735                         return 1;
736                 }
737                 return 0;
738         }
739         if ((p->n_type & TMASK) || (t & TMASK)) /* no cast of pointers */
740                 return 0;
741
742 //printf("concast till %d\n", t);
743 //fwalk(p, eprint, 0);
744
745 #define TYPMSK(y) ((((1LL << (y-1))-1) << 1) | 1)
746         if (p->n_op == ICON) {
747                 val = p->n_lval;
748
749                 if (t == BOOL) {
750                         if (val)
751                                 p->n_lval = 1;
752                 } else if (t <= ULONGLONG) {
753                         p->n_lval = val & TYPMSK(sztable[t]);
754                         if (!ISUNSIGNED(t)) {
755                                 if (val & (1LL << (sztable[t]-1)))
756                                         p->n_lval |= ~TYPMSK(sztable[t]);
757                         }
758                 } else if (t <= LDOUBLE) {
759                         p->n_op = FCON;
760                         p->n_dcon = FLOAT_CAST(valp->n_type);
761                 }
762         } else { /* p->n_op == FCON */
763                 if (t == BOOL) {
764                         p->n_op = ICON;
765                         p->n_lval = FLOAT_NE(p->n_dcon,0.0);
766                         p->n_sp = NULL;
767                 } else if (t <= ULONGLONG) {
768                         p->n_op = ICON;
769                         p->n_lval = ISUNSIGNED(t) ? /* XXX FIXME */
770                             ((U_CONSZ)p->n_dcon) : p->n_dcon;
771                         p->n_sp = NULL;
772                 } else {
773                         p->n_dcon = t == FLOAT ? (float)p->n_dcon :
774                             t == DOUBLE ? (double)p->n_dcon : p->n_dcon;
775                 }
776         }
777         p->n_type = t;
778 //fwalk(p, eprint, 0);
779         return 1;
780 }
781
782 /*
783  * Do a conditional branch.
784  */
785 void
786 cbranch(NODE *pNODE *q)
787 {
788         p = buildtree(CBRANCHpq);
789         if (p->n_left->n_op == ICON) {
790                 if (p->n_left->n_lval != 0) {
791                         branch((int)q->n_lval); /* branch always */
792                         reached = 0;
793                 }
794                 tfree(p);
795                 tfree(q);
796                 return;
797         }
798         ecomp(p);
799 }
800
801 NODE *
plunky
1.3
802 strargs(register NODE *p)
803 {
804         /* rewrite structure flavored arguments */
ragge
1.1
805
806         ifp->n_op == CM ){
807                 p->n_left = strargsp->n_left );
808                 p->n_right = strargsp->n_right );
809                 returnp );
810                 }
811
812         ifp->n_type == STRTY || p->n_type == UNIONTY ){
813                 p = block(STARGpNILp->n_typep->n_dfp->n_ap);
814                 p->n_left = buildtreeADDROFp->n_leftNIL );
815                 p = clocal(p);
816                 }
817         returnp );
818 }
819
820 /*
821  * apply the op o to the lval part of p; if binary, rhs is val
822  */
823 int
824 conval(NODE *pint oNODE *q)
825 {
826         TWORD tl = p->n_typetr = q->n_typetd;
827         int iu;
828         CONSZ val;
829         U_CONSZ v1v2;
830
831         val = q->n_lval;
832
833         /* make both sides same type */
834         if (tl < BTMASK && tr < BTMASK) {
835                 td = tl > tr ? tl : tr;
836                 if (td < INT)
837                         td = INT;
838                 u = ISUNSIGNED(td);
839                 if (tl != td)
840                         p = makety(ptd000);
841                 if (tr != td)
842                         q = makety(qtd000);
843         } else
844                 u = ISUNSIGNED(tl) || ISUNSIGNED(tr);
845         ifu && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE);
846
847         if (p->n_sp != NULL && q->n_sp != NULL)
848                 return(0);
849         if (q->n_sp != NULL && o != PLUS)
850                 return(0);
851         if (p->n_sp != NULL && o != PLUS && o != MINUS)
852                 return(0);
853
854         v1 = p->n_lval;
855         v2 = q->n_lval;
856         if (v2 == 0 && (cdope(o) & DIVFLG))
857                 return 0/* leave division by zero to runtime */
858         switcho ){
859
860         case PLUS:
861                 p->n_lval += val;
862                 if (p->n_sp == NULL) {
863                         p->n_right = q->n_right;
864                         p->n_type = q->n_type;
865                 }
866                 break;
867         case MINUS:
868                 p->n_lval -= val;
869                 break;
870         case MUL:
871                 p->n_lval *= val;
872                 break;
873         case DIV:
874                 if (u) {
875                         v1 /= v2;
876                         p->n_lval = v1;
877                 } else
878                         p->n_lval /= val;
879                 break;
880         case MOD:
881                 if (u) {
882                         v1 %= v2;
883                         p->n_lval = v1;
884                 } else
885                         p->n_lval %= val;
886                 break;
887         case AND:
888                 p->n_lval &= val;
889                 break;
890         case OR:
891                 p->n_lval |= val;
892                 break;
893         case ER:
894                 p->n_lval ^= val;
895                 break;
896         case LS:
897                 i = (int)val;
898                 p->n_lval = p->n_lval << i;
899                 break;
900         case RS:
901                 i = (int)val;
902                 if (u) {
903                         v1 = v1 >> i;
904                         p->n_lval = v1;
905                 } else
906                         p->n_lval = p->n_lval >> i;
907                 break;
908
909         case UMINUS:
910                 p->n_lval = - p->n_lval;
911                 break;
912         case COMPL:
913                 p->n_lval = ~p->n_lval;
914                 break;
915         case NOT:
916                 p->n_lval = !p->n_lval;
917                 break;
918         case LT:
919                 p->n_lval = p->n_lval < val;
920                 break;
921         case LE:
922                 p->n_lval = p->n_lval <= val;
923                 break;
924         case GT:
925                 p->n_lval = p->n_lval > val;
926                 break;
927         case GE:
928                 p->n_lval = p->n_lval >= val;
929                 break;
930         case ULT:
931                 p->n_lval = v1 < v2;
932                 break;
933         case ULE:
934                 p->n_lval = v1 <= v2;
935                 break;
936         case UGT:
937                 p->n_lval = v1 > v2;
938                 break;
939         case UGE:
940                 p->n_lval = v1 >= v2;
941                 break;
942         case EQ:
943                 p->n_lval = p->n_lval == val;
944                 break;
945         case NE:
946                 p->n_lval = p->n_lval != val;
947                 break;
948         case ANDAND:
949                 p->n_lval = p->n_lval && val;
950                 break;
951         case OROR:
952                 p->n_lval = p->n_lval || val;
953                 break;
954         default:
955                 return(0);
956                 }
957         /* Do the best in making everything type correct after calc */
958         if (p->n_sp == NULL && q->n_sp == NULL)
959                 p->n_lval = valcast(p->n_lvalp->n_type);
960         return(1);
961         }
962
963 /*
964  * Ensure that v matches the type t; sign- or zero-extended
965  * as suitable to CONSZ.
966  * Only to be used for integer types.
967  */
968 CONSZ
969 valcast(CONSZ vTWORD t)
970 {
971         CONSZ r;
972         int sz;
973
974         if (t < CHAR || t > ULONGLONG)
975                 return v/* cannot cast */
976
977         if (t >= LONGLONG)
978                 return v/* already largest */
979
980 #define M(x)    ((((1ULL << ((x)-1)) - 1) << 1) + 1)
981 #define NOTM(x) (~M(x))
982 #define SBIT(x) (1ULL << ((x)-1))
983
984         sz = (int)tsize(tNULLNULL);
985         r = v & M(sz);
986         if (!ISUNSIGNED(t) && (SBIT(sz) & r))
987                 r = r | NOTM(sz);
988         return r;
989 }
990
991 /*
plunky
1.13
992  * Checks p for the existence of a pun.  This is called when the op of p
ragge
1.1
993  * is ASSIGN, RETURN, CAST, COLON, or relational.
994  * One case is when enumerations are used: this applies only to lint.
995  * In the other case, one operand is a pointer, the other integer type
996  * we check that this integer is in fact a constant zero...
997  * in the case of ASSIGN, any assignment of pointer to integer is illegal
998  * this falls out, because the LHS is never 0.
999  * XXX - check for COMOPs in assignment RHS?
1000  */
1001 void
1002 chkpun(NODE *p)
1003 {
1004         union dimfun *d1, *d2;
1005         NODE *q;
1006         int t1t2;
1007
1008         t1 = p->n_left->n_type;
1009         t2 = p->n_right->n_type;
1010
1011         switch (p->n_op) {
1012         case RETURN:
1013                 /* return of void allowed but nothing else */
1014                 if (t1 == VOID && t2 == VOID)
1015                         return;
1016                 if (t1 == VOID) {
1017                         werror("returning value from void function");
1018                         return;
1019                 }
1020                 if (t2 == VOID) {
1021                         uerror("using void value");
1022                         return;
1023                 }
plunky
1.6
1024                 break;
ragge
1.1
1025         case COLON:
1026                 if (t1 == VOID && t2 == VOID)
1027                         return;
1028                 break;
1029         default:
1030                 if ((t1 == VOID && t2 != VOID) || (t1 != VOID && t2 == VOID)) {
1031                         uerror("value of void expression used");
1032                         return;
1033                 }
1034                 break;
1035         }
1036
1037         /* allow void pointer assignments in any direction */
1038         if (BTYPE(t1) == VOID && (t2 & TMASK))
1039                 return;
1040         if (BTYPE(t2) == VOID && (t1 & TMASK))
1041                 return;
1042
1043         /* boolean have special syntax */
1044         if (t1 == BOOL) {
1045                 if (!ISARY(t2)) /* Anything scalar */
1046                         return;
1047         }
1048
1049         if (ISPTR(t1) || ISARY(t1))
1050                 q = p->n_right;
1051         else
1052                 q = p->n_left;
1053
1054         if (!ISPTR(q->n_type) && !ISARY(q->n_type)) {
1055                 if (q->n_op != ICON || q->n_lval != 0)
1056                         werror("illegal combination of pointer and integer");
1057         } else {
1058                 if (t1 == t2) {
1059                         if (ISSOU(BTYPE(t1)) &&
1060                             !suemeq(p->n_left->n_app->n_right->n_ap))
1061                                 werror("illegal structure pointer combination");
1062                         return;
1063                 }
1064                 d1 = p->n_left->n_df;
1065                 d2 = p->n_right->n_df;
1066                 for (;;) {
1067                         if (ISARY(t1) || ISPTR(t1)) {
1068                                 if (!ISARY(t2) && !ISPTR(t2))
1069                                         break;
1070                                 if (ISARY(t1) && ISARY(t2) && d1->ddim != d2->ddim) {
1071                                         werror("illegal array size combination");
1072                                         return;
1073                                 }
1074                                 if (ISARY(t1))
1075                                         ++d1;
1076                                 if (ISARY(t2))
1077                                         ++d2;
1078                         } else if (ISFTN(t1)) {
1079                                 if (chkftn(d1->dfund2->dfun)) {
1080                                         werror("illegal function "
1081                                             "pointer combination");
1082                                         return;
1083                                 }
1084                                 ++d1;
1085                                 ++d2;
1086                         } else
1087                                 break;
1088                         t1 = DECREF(t1);
1089                         t2 = DECREF(t2);
1090                 }
1091                 if (DEUNSIGN(t1) != DEUNSIGN(t2))
plunky
1.14
1092                         warner(Wpointer_sign);
ragge
1.1
1093         }
1094 }
1095
1096 static NODE *
1097 offplus(NODE *pint offTWORD tTWORD qunion dimfun *dstruct attr *ap) {
1098         if (off != 0) {
1099                 p = block(PLUSpoffcon(offtdap), tdap);
1100                 p->n_qual = q;
1101                 p = optim(p);
1102         }
1103
1104         return buildtree(UMULpNIL);
1105 }
1106
1107 NODE *
1108 stref(NODE *p)
1109 {
1110         NODE *r;
1111         struct attr *ap, *xap, *yap;
1112         union dimfun *d;
1113         TWORD tq;
1114         int dsc;
1115         OFFSZ off;
1116         struct symtab *s;
1117
1118         /* make p->x */
1119         /* this is also used to reference automatic variables */
1120
1121         s = p->n_right->n_sp;
1122         nfree(p->n_right);
1123         r = nfree(p);
ragge
1.10
1124 #ifdef GCC_COMPAT
ragge
1.1
1125         xap = attr_find(r->n_apGCC_ATYP_PACKED);
ragge
1.10
1126 #endif
ragge
1.1
1127
1128         p = pconvert(r);
1129
1130         /* make p look like ptr to x */
1131
1132         if (!ISPTR(p->n_type))
1133                 p->n_type = PTR+UNIONTY;
1134
1135         t = INCREF(s->stype);
1136         q = INCQAL(s->squal);
1137         d = s->sdf;
1138         ap = s->sap;
ragge
1.10
1139 #ifdef GCC_COMPAT
ragge
1.1
1140         if ((yap = attr_find(apGCC_ATYP_PACKED)) != NULL)
1141                 xap = yap;
1142         else if (xap != NULL)
1143                 ap = attr_add(apattr_dup(xap3));
ragge
1.10
1144 #else
1145         xap = yap = NULL;
1146 #endif
ragge
1.1
1147         /* xap set if packed struct */
1148
1149         p = makety(ptqdap);
1150         if (ISFTN(s->stype)) {
1151                 /* direct class call */
1152                 p = block(NMLISTpnametree(s), INT00);
1153                 return p;
1154         }
1155
1156         /* compute the offset to be added */
1157
1158         off = s->soffset;
1159         dsc = s->sclass;
1160
1161         if (dsc & FIELD) {
1162                 TWORD ftyp = s->stype;
1163                 int fal = talign(ftypap);
1164                 off = (off/fal)*fal;
1165                 p = offplus(pofftqdap);
1166                 p = block(FLDpNILftyp0ap);
1167                 p->n_qual = q;
1168                 p->n_rval = PKFIELD(dsc&FLDSIZs->soffset%fal);
1169         } else {
1170                 p = offplus(pofftqdap);
1171 #ifndef CAN_UNALIGN
1172                 /* if target cannot handle unaligned addresses, fix here */
1173 #endif
1174         }
1175
1176         p = clocal(p);
1177         return p;
1178 }
1179
1180 int
plunky
1.3
1181 notlval(register NODE *p)
1182 {
ragge
1.1
1183         /* return 0 if p an lvalue, 1 otherwise */
1184
1185         again:
1186
1187         switchp->n_op ){
1188
1189         case FLD:
1190                 p = p->n_left;
1191                 goto again;
1192
1193         case NAME:
1194         case OREG:
1195         case UMUL:
1196                 ifISARY(p->n_type) || ISFTN(p->n_type) ) return(1);
1197         case TEMP:
1198         case REG:
1199                 return(0);
1200
1201         default:
1202                 return(1);
plunky
1.3
1203         }
1204 }
ragge
1.1
1205
1206 /* make a constant node with value i */
1207 NODE *
1208 bcon(int i)
1209 {
1210         return xbcon(iNULLINT);
1211 }
1212
1213 NODE *
1214 xbcon(CONSZ val