Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20081019152220

Diff

Diff from 1.208 to:

Annotations

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

Annotated File View

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