Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20080904094133

Diff

Diff from 1.206 to:

Annotations

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

Annotated File View

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