Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20110602145800

Diff

Diff from 1.285 to:

Annotations

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

Annotated File View

plunky
1.285
1 /*      $Id: trees.c,v 1.285 2011/06/02 14:58:00 plunky Exp $   */
ragge
1.51
2 /*
3  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 /*
30  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
31  *
32  * Redistribution and use in source and binary forms, with or without
33  * modification, are permitted provided that the following conditions
34  * are met:
35  *
36  * Redistributions of source code and documentation must retain the above
37  * copyright notice, this list of conditions and the following disclaimer.
38  * Redistributions in binary form must reproduce the above copyright
39  * notice, this list of conditionsand the following disclaimer in the
40  * documentation and/or other materials provided with the distribution.
41  * All advertising materials mentioning features or use of this software
42  * must display the following acknowledgement:
43  *      This product includes software developed or owned by Caldera
44  *      International, Inc.
45  * Neither the name of Caldera International, Inc. nor the names of other
46  * contributors may be used to endorse or promote products derived from
47  * this software without specific prior written permission.
48  *
49  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
50  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
51  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
52  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
53  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
54  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
56  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
58  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
59  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
60  * POSSIBILITY OF SUCH DAMAGE.
61  */
62 /*
63  * Some of the changes from 32V include:
64  * - Understand "void" as type.
65  * - Handle enums as ints everywhere.
ragge
1.57
66  * - Convert some C-specific ops into branches.
ragge
1.51
67  */
68
ragge
1.1
69 # include "pass1.h"
ragge
1.51
70 # include "pass2.h"
ragge
1.1
71
ragge
1.16
72 # include <stdarg.h>
gmcgarry
1.219
73 # include <string.h>
ragge
1.1
74
ragge
1.51
75 static void chkpun(NODE *p);
76 static int opact(NODE *p);
77 static int moditype(TWORD);
ragge
1.45
78 static NODE *strargs(NODE *);
ragge
1.57
79 static void rmcops(NODE *p);
ragge
1.269
80 void putjops(NODE *, void *);
ragge
1.218
81 static struct symtab *findmember(struct symtab *, char *);
ragge
1.189
82 int inftn/* currently between epilog/prolog */
ragge
1.2
83
gmcgarry
1.238
84 static char *tnames[] = {
85         "undef",
86         "farg",
87         "char",
88         "unsigned char",
89         "short",
90         "unsigned short",
91         "int",
92         "unsigned int",
93         "long",
94         "unsigned long",
95         "long long",
96         "unsigned long long",
97         "float",
98         "double",
99         "long double",
100         "strty",
101         "unionty",
102         "enumty",
103         "moety",
104         "void",
105         "signed"/* pass1 */
106         "bool"/* pass1 */
107         "fimag"/* pass1 */
108         "dimag"/* pass1 */
109         "limag"/* pass1 */
110         "fcomplex"/* pass1 */
111         "dcomplex"/* pass1 */
112         "lcomplex"/* pass1 */
113         "enumty"/* pass1 */
114         "?""?"
115 };
116
ragge
1.1
117 /*      some special actions, used in finding the type of nodes */
118 # define NCVT 01
119 # define PUN 02
120 # define TYPL 04
121 # define TYPR 010
122 # define TYMATCH 040
123 # define LVAL 0100
124 # define CVTO 0200
125 # define CVTL 0400
126 # define CVTR 01000
127 # define PTMATCH 02000
128 # define OTHER 04000
129 # define NCVTR 010000
ragge
1.275
130 # define PROML 020000   /* promote left operand */
ragge
1.1
131
132 /* node conventions:
133
134         NAME:   rval>0 is stab index for external
135                 rval<0 is -inlabel number
136                 lval is offset in bits
137         ICON:   lval has the value
138                 rval has the STAB index, or - label number,
139                         if a name whose address is in the constant
140                 rval = NONAME means no name
141         REG:    rval is reg. identification cookie
142
143         */
144
ragge
1.30
145 int bdebug = 0;
ragge
1.208
146 extern int negrel[];
147
ragge
1.1
148 NODE *
ragge
1.2
149 buildtree(int oNODE *lNODE *r)
150 {
151         NODE *p, *q;
152         int actions;
153         int opty;
ragge
1.119
154         struct symtab *sp = NULL/* XXX gcc */
ragge
1.2
155         NODE *lr, *ll;
ragge
1.1
156
ragge
1.68
157 #ifdef PCC_DEBUG
ragge
1.128
158         if (bdebug) {
ragge
1.58
159                 printf("buildtree(%s, %p, %p)\n"copst(o), lr);
ragge
1.128
160                 if (lfwalk(leprint0);
161                 if (rfwalk(reprint0);
162         }
ragge
1.68
163 #endif
ragge
1.58
164         opty = coptype(o);
ragge
1.1
165
166         /* check for constants */
167
ragge
1.271
168         if (o == ANDAND || o == OROR || o == NOT) {
169                 if (l->n_op == FCON) {
170                         p = bcon(!FLOAT_ISZERO(l->n_dcon));
171                         nfree(l);
172                         l = p;
173                 }
174                 if (o != NOT && r->n_op == FCON) {
175                         p = bcon(!FLOAT_ISZERO(r->n_dcon));
176                         nfree(r);
177                         r = p;
178                 }
179         }
180
ragge
1.22
181         ifopty == UTYPE && l->n_op == ICON ){
ragge
1.1
182
183                 switcho ){
184
185                 case NOT:
ragge
1.94
186                 case UMINUS:
ragge
1.1
187                 case COMPL:
188                         ifconvallol ) ) return(l);
189                         break;
190                 }
ragge
1.71
191         } else if (o == NOT && l->n_op == FCON) {
ragge
1.274
192                 l = clocal(block(SCONVlNILINT00));
ragge
1.94
193         } else ifo == UMINUS && l->n_op == FCON ){
ragge
1.206
194                         l->n_dcon = FLOAT_NEG(l->n_dcon);
ragge
1.1
195                         return(l);
196
ragge
1.283
197         } else ifo==QUEST &&
198             (l->n_op==ICON || (l->n_op==NAME && ISARY(l->n_type)))) {
ragge
1.41
199                 CONSZ c = l->n_lval;
ragge
1.283
200                 if (l->n_op==NAME)
201                         c = 1/* will become constant later */
ragge
1.41
202                 nfree(l);
203                 if (c) {
ragge
1.215
204                         walkf(r->n_rightputjops0);
ragge
1.41
205                         tfree(r->n_right);
206                         l = r->n_left;
207                 } else {
ragge
1.215
208                         walkf(r->n_leftputjops0);
ragge
1.41
209                         tfree(r->n_left);
210                         l = r->n_right;
ragge
1.1
211                 }
ragge
1.214
212                 nfree(r);
213                 return(l);
ragge
1.155
214         } else ifopty == BITYPE && l->n_op == ICON && r->n_op == ICON ){
ragge
1.1
215
216                 switcho ){
217
ragge
1.159
218                 case PLUS:
219                 case MINUS:
220                 case MUL:
221                 case DIV:
222                 case MOD:
223                         /*
224                          * Do type propagation for simple types here.
225                          * The constant value is correct anyway.
226                          * Maybe this op shortcut should be removed?
227                          */
228                         if (l->n_sp == NULL && r->n_sp == NULL &&
229                             l->n_type < BTMASK && r->n_type < BTMASK) {
230                                 if (l->n_type > r->n_type)
231                                         r->n_type = l->n_type;
232                                 else
233                                         l->n_type = r->n_type;
234                         }
235                         /* FALLTHROUGH */
ragge
1.1
236                 case ULT:
237                 case UGT:
238                 case ULE:
239                 case UGE:
240                 case LT:
241                 case GT:
242                 case LE:
243                 case GE:
244                 case EQ:
ragge
1.48
245                 case NE:
ragge
1.1
246                 case ANDAND:
247                 case OROR:
248                 case AND:
249                 case OR:
250                 case ER:
251                 case LS:
252                 case RS:
ragge
1.200
253                         if (!ISPTR(l->n_type) && !ISPTR(r->n_type)) {
254                                 ifconvallor ) ) {
255                                         nfree(r);
256                                         return(l);
257                                 }
ragge
1.44
258                         }
ragge
1.1
259                         break;
260                 }
ragge
1.44
261         } else if (opty == BITYPE && (l->n_op == FCON || l->n_op == ICON) &&
262             (r->n_op == FCON || r->n_op == ICON) && (o == PLUS || o == MINUS ||
gmcgarry
1.234
263             o == MUL || o == DIV || (o >= EQ && o <= GT) )) {
ragge
1.270
264                 TWORD t;
ragge
1.261
265 #ifndef CC_DIV_0
ragge
1.257
266                 if (o == DIV &&
267                     ((r->n_op == ICON && r->n_lval == 0) ||
268                      (r->n_op == FCON && r->n_dcon == 0.0)))
269                                 goto runtime/* HW dependent */
ragge
1.261
270 #endif
gmcgarry
1.234
271                 if (l->n_op == ICON)
272                         l->n_dcon = FLOAT_CAST(l->n_lvall->n_type);
273                 if (r->n_op == ICON)
274                         r->n_dcon = FLOAT_CAST(r->n_lvalr->n_type);
ragge
1.44
275                 switch(o){
276                 case PLUS:
277                 case MINUS:
278                 case MUL:
279                 case DIV:
280                         switch (o) {
281                         case PLUS:
ragge
1.206
282                                 l->n_dcon = FLOAT_PLUS(l->n_dconr->n_dcon);
283                                 break;
ragge
1.44
284                         case MINUS:
ragge
1.206
285                                 l->n_dcon = FLOAT_MINUS(l->n_dconr->n_dcon);
286                                 break;
ragge
1.44
287                         case MUL:
ragge
1.206
288                                 l->n_dcon = FLOAT_MUL(l->n_dconr->n_dcon);
289                                 break;
ragge
1.44
290                         case DIV:
ragge
1.206
291                                 l->n_dcon = FLOAT_DIV(l->n_dconr->n_dcon);
292                                 break;
ragge
1.44
293                         }
ragge
1.270
294                         t = (l->n_type > r->n_type ? l->n_type : r->n_type);
ragge
1.44
295                         l->n_op = FCON;
ragge
1.270
296                         l->n_type = t;
ragge
1.44
297                         nfree(r);
298                         return(l);
gmcgarry
1.234
299                 case EQ:
300                 case NE:
301                 case LE:
302                 case LT:
303                 case GE:
304                 case GT:
305                         switch (o) {
306                         case EQ:
307                                 l->n_lval = FLOAT_EQ(l->n_dconr->n_dcon);
308                                 break;
309                         case NE:
310                                 l->n_lval = FLOAT_NE(l->n_dconr->n_dcon);
311                                 break;
312                         case LE:
313                                 l->n_lval = FLOAT_LE(l->n_dconr->n_dcon);
314                                 break;
315                         case LT:
316                                 l->n_lval = FLOAT_LT(l->n_dconr->n_dcon);
317                                 break;
318                         case GE:
319                                 l->n_lval = FLOAT_GE(l->n_dconr->n_dcon);
320                                 break;
321                         case GT:
322                                 l->n_lval = FLOAT_GT(l->n_dconr->n_dcon);
323                                 break;
324                         }
325                         nfree(r);
ragge
1.236
326                         r = bcon(l->n_lval);
327                         nfree(l);
328                         return r;
ragge
1.1
329                 }
ragge
1.44
330         }
ragge
1.261
331 #ifndef CC_DIV_0
otto
1.170
332 runtime:
ragge
1.261
333 #endif
ragge
1.30
334         /* its real; we must make a new node */
ragge
1.1
335
ragge
1.274
336         p = block(olrINT00);
ragge
1.1
337
338         actions = opact(p);
339
ragge
1.275
340         if (actions & PROML)
341                 p->n_left = intprom(p->n_left);
342
ragge
1.66
343         if (actions & LVAL) { /* check left descendent */
344                 if (notlval(p->n_left)) {
345                         uerror("lvalue required");
stefan
1.186
346                         nfree(p);
347                         return l;
ragge
1.68
348 #ifdef notyet
ragge
1.67
349                 } else {
350                         if ((l->n_type > BTMASK && ISCON(l->n_qual)) ||
351                             (l->n_type <= BTMASK && ISCON(l->n_qual << TSHIFT)))
352                                 if (blevel > 0)
353                                         uerror("lvalue is declared const");
ragge
1.68
354 #endif
ragge
1.67
355                 }
ragge
1.66
356         }
ragge
1.1
357
358         ifactions & NCVTR ){
ragge
1.22
359                 p->n_left = pconvertp->n_left );
ragge
1.1
360                 }
361         else if( !(actions & NCVT ) ){
362                 switchopty ){
363
364                 case BITYPE:
ragge
1.22
365                         p->n_right = pconvertp->n_right );
ragge
1.1
366                 case UTYPE:
ragge
1.22
367                         p->n_left = pconvertp->n_left );
ragge
1.1
368
369                         }
370                 }
371
ragge
1.64
372         if ((actions&PUN) && (o!=CAST))
ragge
1.1
373                 chkpun(p);
374
375         ifactions & (TYPL|TYPR) ){
376
ragge
1.22
377                 q = (actions&TYPL) ? p->n_left : p->n_right;
ragge
1.1
378
ragge
1.22
379                 p->n_type = q->n_type;
ragge
1.66
380                 p->n_qual = q->n_qual;
ragge
1.29
381                 p->n_df = q->n_df;
ragge
1.252
382                 p->n_ap = q->n_ap;
ragge
1.1
383                 }
384
385         ifactions & CVTL ) p = convertpCVTL );
386         ifactions & CVTR ) p = convertpCVTR );
387         ifactions & TYMATCH ) p = tymatch(p);
388         ifactions & PTMATCH ) p = ptmatch(p);
389
390         ifactions & OTHER ){
ragge
1.252
391                 struct symtab *sp1;
ragge
1.225
392
ragge
1.22
393                 l = p->n_left;
394                 r = p->n_right;
ragge
1.1
395
396                 switch(o){
397
398                 case NAME:
ragge
1.203
399                         cerror("buildtree NAME");
ragge
1.1
400
401                 case STREF:
402                         /* p->x turned into *(p+offset) */
403                         /* rhs must be a name; check correctness */
404
ragge
1.23
405                         /* Find member symbol struct */
406                         if (l->n_type != PTR+STRTY && l->n_type != PTR+UNIONTY){
407                                 uerror("struct or union required");
408                                 break;
409                         }
410
ragge
1.252
411                         if ((sp1 = strmemb(l->n_ap)) == NULL) {
ragge
1.23
412                                 uerror("undefined struct or union");
stefan
1.190
413                                 break;
414                         }
ragge
1.23
415
ragge
1.252
416                         if ((sp = findmember(sp1r->n_name)) == NULL) {
ragge
1.218
417                                 uerror("member '%s' not declared"r->n_name);
stefan
1.190
418                                 break;
419                         }
ragge
1.23
420
421                         r->n_sp = sp;
422                         p = stref(p);
423                         break;
424
ragge
1.94
425                 case UMUL:
ragge
1.93
426                         if (l->n_op == ADDROF) {
ragge
1.41
427                                 nfree(p);
ragge
1.22
428                                 p = l->n_left;
ragge
1.41
429                                 nfree(l);
430                         }
ragge
1.22
431                         if( !ISPTR(l->n_type))uerror("illegal indirection");
432                         p->n_type = DECREF(l->n_type);
ragge
1.67
433                         p->n_qual = DECREF(l->n_qual);
ragge
1.29
434                         p->n_df = l->n_df;
ragge
1.252
435                         p->n_ap = l->n_ap;
ragge
1.1
436                         break;
437
ragge
1.93
438                 case ADDROF:
ragge
1.22
439                         switchl->n_op ){
ragge
1.1
440
ragge
1.94
441                         case UMUL:
ragge
1.41
442                                 nfree(p);
ragge
1.22
443                                 p = l->n_left;
ragge
1.41
444                                 nfree(l);
ragge
1.130
445                         case TEMP:
ragge
1.1
446                         case NAME:
ragge
1.68
447                                 p->n_type = INCREF(l->n_type);
448                                 p->n_qual = INCQAL(l->n_qual);
ragge
1.29
449                                 p->n_df = l->n_df;
ragge
1.252
450                                 p->n_ap = l->n_ap;
ragge
1.1
451                                 break;
452
453                         case COMOP:
ragge
1.41
454                                 nfree(p);
ragge
1.93
455                                 lr = buildtree(ADDROFl->n_rightNIL);
ragge
1.22
456                                 p = buildtreeCOMOPl->n_leftlr );
ragge
1.41
457                                 nfree(l);
ragge
1.1
458                                 break;
459
460                         case QUEST:
ragge
1.93
461                                 lr = buildtreeADDROFl->n_right->n_rightNIL );
462                                 ll = buildtreeADDROFl->n_right->n_leftNIL );
ragge
1.41
463                                 nfree(p); nfree(l->n_right);
ragge
1.22
464                                 p = buildtreeQUESTl->n_leftbuildtreeCOLONlllr ) );
ragge
1.41
465                                 nfree(l);
ragge
1.1
466                                 break;
467
468                         default:
ragge
1.22
469                                 uerror("unacceptable operand of &: %d"l->n_op );
ragge
1.1
470                                 break;
471                                 }
472                         break;
473
474                 case LS:
ragge
1.150
475                 case RS/* must make type size at least int... */
476                         if (p->n_type == CHAR || p->n_type == SHORT) {
ragge
1.274
477                                 p->n_left = makety(lINT000);
ragge
1.150
478                         } else if (p->n_type == UCHAR || p->n_type == USHORT) {
ragge
1.274
479                                 p->n_left = makety(lUNSIGNED000);
ragge
1.150
480                         }
481                         l = p->n_left;
482                         p->n_type = l->n_type;
483                         p->n_qual = l->n_qual;
484                         p->n_df = l->n_df;
ragge
1.252
485                         p->n_ap = l->n_ap;
ragge
1.150
486
487                         /* FALLTHROUGH */
ragge
1.95
488                 case LSEQ:
ragge
1.150
489                 case RSEQ/* ...but not for assigned types */
ragge
1.252
490                         if(tsize(r->n_typer->n_dfr->n_ap) > SZINT)
ragge
1.274
491                                 p->n_right = makety(rINT000);
ragge
1.1
492                         break;
493
494                 case RETURN:
495                 case ASSIGN:
496                 case CAST:
497                         /* structure assignment */
498                         /* take the addresses of the two sides; then make an
ragge
1.2
499                          * operator using STASG and
500                          * the addresses of left and right */
ragge
1.1
501
ragge
1.252
502                         if (strmemb(l->n_ap) != strmemb(r->n_ap))
503                                 uerror("assignment of different structures");
504
505                         r = buildtree(ADDROFrNIL);
506
507                         l = block(STASGlrr->n_typer->n_dfr->n_ap);
508                         l = clocal(l);
ragge
1.1
509
ragge
1.252
510                         ifo == RETURN ){
511                                 nfree(p);
512                                 p = l;
ragge
1.1
513                                 break;
ragge
1.252
514                         }
515
516                         p->n_op = UMUL;
517                         p->n_left = l;
518                         p->n_right = NIL;
519                         break;
520
ragge
1.266
521                 case QUEST/* fixup types of : */
522                         if (r->n_left->n_type != p->n_type)
523                                 r->n_left = makety(r->n_leftp->n_type,
524                                     p->n_qualp->n_dfp->n_ap);
525                         if (r->n_right->n_type != p->n_type)
526                                 r->n_right = makety(r->n_rightp->n_type,
527                                     p->n_qualp->n_dfp->n_ap);
528                         break;
529
ragge
1.1
530                 case COLON:
531                         /* structure colon */
532
ragge
1.252
533                         if (strmemb(l->n_ap) != strmemb(r->n_ap))
ragge
1.26
534                                 uerror"type clash in conditional" );
ragge
1.1
535                         break;
536
537                 case CALL:
ragge
1.45
538                         p->n_right = r = strargs(p->n_right);
ragge
1.171
539                         p = funcode(p);
540                         /* FALLTHROUGH */
ragge
1.95
541                 case UCALL:
ragge
1.23
542                         if (!ISPTR(l->n_type))
543                                 uerror("illegal function");
ragge
1.22
544                         p->n_type = DECREF(l->n_type);
ragge
1.23
545                         if (!ISFTN(p->n_type))
546                                 uerror("illegal function");
547                         p->n_type = DECREF(p->n_type);
ragge
1.252
548                         p->n_df = l->n_df+1/* add one for prototypes */
549                         p->n_ap = l->n_ap;
ragge
1.23
550                         if (p->n_type == STRTY || p->n_type == UNIONTY) {
ragge
1.1
551                                 /* function returning structure */
552                                 /*  make function really return ptr to str., with * */
553
ragge
1.22
554                                 p->n_op += STCALL-CALL;
ragge
1.23
555                                 p->n_type = INCREF(p->n_type);
ragge
1.149
556                                 p = clocal(p); /* before recursing */
ragge
1.94
557                                 p = buildtree(UMULpNIL);
ragge
1.1
558
559                                 }
560                         break;
561
562                 default:
563                         cerror"other code %d"o );
564                         }
565
566                 }
567
ragge
1.11
568         /*
569          * Allow (void)0 casts.
570          * XXX - anything on the right side must be possible to cast.
571          * XXX - remove void types further on.
572          */
ragge
1.50
573         if (p->n_op == CAST && p->n_type == VOID &&
ragge
1.22
574             p->n_right->n_op == ICON)
ragge
1.50
575                 p->n_right->n_type = VOID;
ragge
1.11
576
ragge
1.68
577         if (actions & CVTO)
578                 p = oconvert(p);
ragge
1.1
579         p = clocal(p);
580
ragge
1.30
581 #ifdef PCC_DEBUG
ragge
1.74
582         if (bdebug) {
583                 printf("End of buildtree:\n");
ragge
1.68
584                 fwalk(peprint0);
ragge
1.74
585         }
ragge
1.30
586 #endif
ragge
1.1
587
588         return(p);
589
590         }
591
ragge
1.218
592 /* Find a member in a struct or union.  May be an unnamed member */
593 static struct symtab *
594 findmember(struct symtab *spchar *s)
595 {
596         struct symtab *sp2, *sp3;
597
598         for (; sp != NULLsp = sp->snext) {
599                 if (sp->sname[0] == '*') {
600                         /* unnamed member, recurse down */
ragge
1.252
601                         if ((sp2 = findmember(strmemb(sp->sap), s))) {
ragge
1.218
602                                 sp3 = tmpalloc(sizeof (struct symtab));
603                                 *sp3 = *sp2;
604                                 sp3->soffset += sp->soffset;
605                                 return sp3;
606                         }
607                 } else if (sp->sname == s)
608                         return sp;
609         }
610         return NULL;
611 }
612
613
ragge
1.107
614 /*
ragge
1.214
615  * Check if there will be a lost label destination inside of a ?:
616  * It cannot be reached so just print it out.
617  */
ragge
1.269
618 void
ragge
1.215
619 putjops(NODE *pvoid *arg)
ragge
1.214
620 {
621         if (p->n_op == COMOP && p->n_left->n_op == GOTO)
622                 plabel(p->n_left->n_left->n_lval+1);
623 }
624
625 /*
ragge
1.199
626  * Build a name node based on a symtab entry.
627  * broken out from buildtree().
628  */
629 NODE *
630 nametree(struct symtab *sp)
631 {
632         NODE *p;
633
ragge
1.252
634         p = block(NAMENILNILsp->stypesp->sdfsp->sap);
ragge
1.199
635         p->n_qual = sp->squal;
636         p->n_sp = sp;
637
638 #ifndef NO_C_BUILTINS
639         if (sp->sname[0] == '_' && strncmp(sp->sname"__builtin_"10) == 0)
640                 return p;  /* do not touch builtins here */
641         
642 #endif
643
644         if (sp->sflags & STNODE) {
645                 /* Generated for optimizer */
646                 p->n_op = TEMP;
647                 p->n_rval = sp->soffset;
648         }
649
650 #ifdef GCC_COMPAT
651         /* Get a label name */
652         if (sp->sflags == SLBLNAME) {
653                 p->n_type = VOID;
654         }
655 #endif
656         if (sp->stype == UNDEF) {
657                 uerror("%s undefined"sp->sname);
658                 /* make p look reasonable */
659                 p->n_type = INT;
660                 p->n_df = NULL;
661                 defid(pSNULL);
662         }
663         if (sp->sclass == MOE) {
664                 p->n_op = ICON;
665                 p->n_lval = sp->soffset;
666                 p->n_df = NULL;
667                 p->n_sp = NULL;
668         }
669         return clocal(p);
670 }
671
672 /*
ragge
1.241
673  * Cast a node to another type by inserting a cast.
ragge
1.240
674  * Just a nicer interface to buildtree.
675  * Returns the new tree.
676  */
677 NODE *
678 cast(NODE *pTWORD tTWORD u)
679 {
680         NODE *q;
681
ragge
1.274
682         q = block(NAMENILNILt00);
ragge
1.240
683         q->n_qual = u;
684         q = buildtree(CASTqp);
685         p = q->n_right;
686         nfree(q->n_left);
687         nfree(q);
688         return p;
689 }
690
691 /*
ragge
1.241
692  * Cast and complain if necessary by not inserining a cast.
693  */
694 NODE *
ragge
1.252
695 ccast(NODE *pTWORD tTWORD uunion dimfun *dfstruct attr *ap)
ragge
1.241
696 {
697         NODE *q;
698
699         /* let buildtree do typechecking (and casting) */ 
ragge
1.252
700         q = block(NAMENILNILtdfap);
ragge
1.241
701         p = buildtree(ASSIGNqp);
702         nfree(p->n_left);
703         q = optim(p->n_right);
704         nfree(p);
705         return q;
706 }
707
708 /*
ragge
1.284
709  * Do an actual cast of a constant (if possible).
710  * Routine assumes 2-complement (is there anything else today?)
711  * Returns 1 if handled, 0 otherwise.
712  */
713 int
714 concast(NODE *pTWORD t)
715 {
716         extern short sztable[];
717         CONSZ val;
718
719         if (p->n_op != ICON && p->n_op != FCON/* only constants */
720                 return 0;
721         if (p->n_op == ICON && p->n_sp != NULL) { /* no addresses */
722                 if (t == BOOL) {
723                         p->n_lval = 1p->n_type = BOOLp->n_sp = NULL;
724                         return 1;
725                 }
726                 return 0;
727         }
728         if ((p->n_type & TMASK) || (t & TMASK)) /* no cast of pointers */
729                 return 0;
730
731 //printf("concast till %d\n", t);
732 //fwalk(p, eprint, 0);
733
734 #define TYPMSK(y) ((((1LL << (y-1))-1) << 1) | 1)
735         if (p->n_op == ICON) {
736                 val = p->n_lval;
737
738                 if (t == BOOL) {
739                         if (val)
740                                 p->n_lval = 1;
741                 } else if (t <= ULONGLONG) {
742                         p->n_lval = val & TYPMSK(sztable[t]);
743                         if (!ISUNSIGNED(t)) {
744                                 if (val & (1LL << (sztable[t]-1)))
745                                         p->n_lval |= ~TYPMSK(sztable[t]);
746                         }
747                 } else if (t <= LDOUBLE) {
748                         p->n_op = FCON;
749                         p->n_dcon = FLOAT_CAST(valp->n_type);
750                 }
751         } else { /* p->n_op == FCON */
752                 if (t == BOOL) {
753                         p->n_op = ICON;
754                         p->n_lval = FLOAT_NE(p->n_dcon,0.0);
755                         p->n_sp = NULL;
756                 } else if (t <= ULONGLONG) {
757                         p->n_op = ICON;
758                         p->n_lval = ISUNSIGNED(t) ? /* XXX FIXME */
759                             ((U_CONSZ)p->n_dcon) : p->n_dcon;
760                         p->n_sp = NULL;
761                 } else {
762                         p->n_dcon = t == FLOAT ? (float)p->n_dcon :
763                             t == DOUBLE ? (double)p->n_dcon : p->n_dcon;
764                 }
765         }
766         p->n_type = t;
767 //fwalk(p, eprint, 0);
768         return 1;
769 }
770
771 /*
ragge
1.107
772  * Do a conditional branch.
773  */
774 void
775 cbranch(NODE *pNODE *q)
776 {
777         p = buildtree(CBRANCHpq);
778         if (p->n_left->n_op == ICON) {
ragge
1.208
779                 if (p->n_left->n_lval != 0) {
ragge
1.107
780                         branch(q->n_lval); /* branch always */
ragge
1.208
781                         reached = 0;
782                 }
ragge
1.107
783                 tfree(p);
784                 tfree(q);
785                 return;
786         }
787         ecomp(p);
788 }
789
ragge
1.1
790 NODE *
ragge
1.45
791 strargsp ) register NODE *p;  { /* rewrite structure flavored arguments */
ragge
1.1
792
ragge
1.45
793         ifp->n_op == CM ){
794                 p->n_left = strargsp->n_left );
795                 p->n_right = strargsp->n_right );
ragge
1.1
796                 returnp );
797                 }
798
ragge
1.22
799         ifp->n_type == STRTY || p->n_type == UNIONTY ){
ragge
1.252
800                 p = block(STARGpNILp->n_typep->n_dfp->n_ap);
ragge
1.93
801                 p->n_left = buildtreeADDROFp->n_leftNIL );
ragge
1.1
802                 p = clocal(p);
803                 }
804         returnp );
ragge
1.2
805 }
ragge
1.1
806
ragge
1.2
807 /*
808  * apply the op o to the lval part of p; if binary, rhs is val
809  */
810 int
811 conval(NODE *pint oNODE *q)
812 {
ragge
1.264
813         TWORD tl = p->n_typetr = q->n_typetd;
ragge
1.1
814         int iu;
815         CONSZ val;
ragge
1.159
816         U_CONSZ v1v2;
ragge
1.1
817
ragge
1.22
818         val = q->n_lval;
ragge
1.264
819
820         /* make both sides same type */
ragge
1.273
821         if (tl < BTMASK && tr < BTMASK) {
ragge
1.264
822                 td = tl > tr ? tl : tr;
823                 if (td < INT)
824                         td = INT;
825                 u = ISUNSIGNED(td);
826                 if (tl != td)
ragge
1.274
827                         p = makety(ptd000);
ragge
1.264
828                 if (tr != td)
ragge
1.274
829                         q = makety(qtd000);
ragge
1.264
830         } else
831                 u = ISUNSIGNED(tl) || ISUNSIGNED(tr);
ragge
1.1
832         ifu && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE);
833
ragge
1.23
834         if (p->n_sp != NULL && q->n_sp != NULL)
835                 return(0);
836         if (q->n_sp != NULL && o != PLUS)
837                 return(0);
838         if (p->n_sp != NULL && o != PLUS && o != MINUS)
839                 return(0);
ragge
1.264
840
ragge
1.161
841         v1 = p->n_lval;
842         v2 = q->n_lval;
ragge
1.1
843         switcho ){
844
845         case PLUS:
ragge
1.22
846                 p->n_lval += val;
ragge
1.23
847                 if (p->n_sp == NULL) {
ragge
1.237
848                         p->n_right = q->n_right;
ragge
1.22
849                         p->n_type = q->n_type;
ragge
1.23
850                 }
ragge
1.1
851                 break;
852         case MINUS:
ragge
1.22
853                 p->n_lval -= val;
ragge
1.1
854                 break;
855         case MUL:
ragge
1.22
856                 p->n_lval *= val;
ragge
1.1
857                 break;
858         case DIV:
ragge
1.46
859                 if (val == 0)
860                         uerror("division by 0");
ragge
1.159
861                 else  {
862                         if (u) {
863                                 v1 /= v2;
864                                 p->n_lval = v1;
865                         } else
866                                 p->n_lval /= val;
867                 }
ragge
1.1
868                 break;
869         case MOD:
ragge
1.46
870                 if (val == 0)
871                         uerror("division by 0");
ragge
1.159
872                 else  {
873                         if (u) {
874                                 v1 %= v2;
875                                 p->n_lval = v1;
876                         } else
877                                 p->n_lval %= val;
878                 }
ragge
1.1
879                 break;
880         case AND:
ragge
1.22
881                 p->n_lval &= val;
ragge
1.1
882                 break;
883         case OR:
ragge
1.22
884                 p->n_lval |= val;
ragge
1.1
885                 break;
886         case ER:
ragge
1.22
887                 p->n_lval ^= val;
ragge
1.1
888                 break;
889         case LS:
gmcgarry
1.238
890                 i = (int)val;
ragge
1.22
891                 p->n_lval = p->n_lval << i;
ragge
1.1
892                 break;
893         case RS:
gmcgarry
1.238
894                 i = (int)val;
ragge
1.159
895                 if (u) {
896                         v1 = v1 >> i;
897                         p->n_lval = v1;
898                 } else
899                         p->n_lval = p->n_lval >> i;
ragge
1.1
900                 break;
901