Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20160305153124

Diff

Diff from 1.21 to:

Annotations

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

Annotated File View

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