Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20081026110604

Diff

Diff from 1.210 to:

Annotations

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

Annotated File View

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