Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:mickey:20081101082937

Diff

Diff from 1.213 to:

Annotations

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

Annotated File View

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