Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030707141035

Diff

Diff from 1.50 to:

Annotations

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

Annotated File View

ragge
1.1
1 # include "pass1.h"
ragge
1.9
2 # include "pass2.h"     /* for NOPREF */
ragge
1.1
3
4 # include <setjmp.h>
ragge
1.16
5 # include <stdarg.h>
6 # include <string.h>
ragge
1.1
7
ragge
1.2
8 void chkpun(NODE *p);
9 int opact(NODE *p);
10 int moditype(TWORD);
ragge
1.45
11 static NODE *strargs(NODE *);
ragge
1.2
12
13 /* corrections when in violation of lint */
ragge
1.1
14
15 /*      some special actions, used in finding the type of nodes */
16 # define NCVT 01
17 # define PUN 02
18 # define TYPL 04
19 # define TYPR 010
20 # define TYMATCH 040
21 # define LVAL 0100
22 # define CVTO 0200
23 # define CVTL 0400
24 # define CVTR 01000
25 # define PTMATCH 02000
26 # define OTHER 04000
27 # define NCVTR 010000
28
29 /* node conventions:
30
31         NAME:   rval>0 is stab index for external
32                 rval<0 is -inlabel number
33                 lval is offset in bits
34         ICON:   lval has the value
35                 rval has the STAB index, or - label number,
36                         if a name whose address is in the constant
37                 rval = NONAME means no name
38         REG:    rval is reg. identification cookie
39
40         */
41
ragge
1.30
42 int bdebug = 0;
43
ragge
1.1
44 NODE *
ragge
1.2
45 buildtree(int oNODE *lNODE *r)
46 {
47         NODE *p, *q;
48         int actions;
49         int opty;
50         struct symtab *sp;
51         NODE *lr, *ll;
ragge
1.23
52         char *name;
ragge
1.26
53         struct symtab **elem;
ragge
1.1
54
55 # ifndef BUG1
ragge
1.2
56         if (bdebug)
57                 printf("buildtree(%s, %p, %p)\n"opst[o], lr);
ragge
1.1
58 # endif
59         opty = optype(o);
60
61         /* check for constants */
62
ragge
1.22
63         ifopty == UTYPE && l->n_op == ICON ){
ragge
1.1
64
65                 switcho ){
66
67                 case NOT:
68                 case UNARY MINUS:
69                 case COMPL:
70                         ifconvallol ) ) return(l);
71                         break;
72
73                 }
ragge
1.44
74         } else ifo == UNARY MINUS && l->n_op == FCON ){
75                         ifl->n_type == FLOAT )
ragge
1.22
76                                 l->n_fcon = -l->n_fcon;
ragge
1.1
77                         else
ragge
1.22
78                                 l->n_dcon = -l->n_dcon;
ragge
1.1
79                         return(l);
80
ragge
1.44
81         } else ifo==QUEST && l->n_op==ICON ) {
ragge
1.41
82                 CONSZ c = l->n_lval;
83                 nfree(l);
84                 if (c) {
85                         tfree(r->n_right);
86                         l = r->n_left;
87                         nfree(r);
88                         return(l);
89                 } else {
90                         tfree(r->n_left);
91                         l = r->n_right;
92                         nfree(r);
93                         return(l);
ragge
1.1
94                 }
ragge
1.44
95         } else if( (o==ANDAND || o==OROR) && (l->n_op==ICON||r->n_op==ICON) )
96                 goto ccwarn;
ragge
1.1
97
ragge
1.22
98         else ifopty == BITYPE && l->n_op == ICON && r->n_op == ICON ){
ragge
1.1
99
100                 switcho ){
101
102                 case ULT:
103                 case UGT:
104                 case ULE:
105                 case UGE:
106                 case LT:
107                 case GT:
108                 case LE:
109                 case GE:
110                 case EQ:
ragge
1.48
111                 case NE:
ragge
1.1
112                 case ANDAND:
113                 case OROR:
114                 case CBRANCH:
115
116                 ccwarn:
117
118                 case PLUS:
119                 case MINUS:
120                 case MUL:
121                 case DIV:
122                 case MOD:
123                 case AND:
124                 case OR:
125                 case ER:
126                 case LS:
127                 case RS:
128                         ifconvallor ) ) {
ragge
1.41
129                                 nfree(r);
ragge
1.1
130                                 return(l);
ragge
1.44
131                         }
ragge
1.1
132                         break;
133                 }
ragge
1.44
134         } else if (opty == BITYPE && (l->n_op == FCON || l->n_op == ICON) &&
135             (r->n_op == FCON || r->n_op == ICON) && (o == PLUS || o == MINUS ||
136             o == MUL || o == DIV)) {
137                 switch(o){
138                 case PLUS:
139                 case MINUS:
140                 case MUL:
141                 case DIV:
142                         if (l->n_op == ICON)
143                                 l->n_dcon = l->n_lval;
144                         else if (l->n_type == FLOAT)
145                                 l->n_dcon = l->n_fcon;
146                         if (r->n_op == ICON)
147                                 r->n_dcon = r->n_lval;
148                         else if (r->n_type == FLOAT)
149                                 r->n_dcon = r->n_fcon;
150                         switch (o) {
151                         case PLUS:
152                                 l->n_dcon += r->n_dconbreak;
153                         case MINUS:
154                                 l->n_dcon -= r->n_dconbreak;
155                         case MUL:
156                                 l->n_dcon *= r->n_dconbreak;
157                         case DIV:
158                                 if (r->n_dcon == 0)
159                                         uerror("division by 0.");
160                                 else
161                                         l->n_dcon /= r->n_dcon;
162                         }
163                         l->n_op = FCON;
164                         l->n_type = DOUBLE;
165                         l->n_sue = MKSUE(DOUBLE);
166                         nfree(r);
167                         return(l);
ragge
1.1
168                 }
ragge
1.44
169         }
ragge
1.1
170
ragge
1.30
171         /* its real; we must make a new node */
ragge
1.1
172
ragge
1.26
173         p = block(olrINT0MKSUE(INT));
ragge
1.1
174
175         actions = opact(p);
176
177         ifactions&LVAL ){ /* check left descendent */
ragge
1.22
178                 ifnotlval(p->n_left) ) {
ragge
1.30
179                         uerror"lvalue required" );
ragge
1.1
180                         }
181                 }
182
183         ifactions & NCVTR ){
ragge
1.22
184                 p->n_left = pconvertp->n_left );
ragge
1.1
185                 }
186         else if( !(actions & NCVT ) ){
187                 switchopty ){
188
189                 case BITYPE:
ragge
1.22
190                         p->n_right = pconvertp->n_right );
ragge
1.1
191                 case UTYPE:
ragge
1.22
192                         p->n_left = pconvertp->n_left );
ragge
1.1
193
194                         }
195                 }
196
ragge
1.7
197         if ((actions&PUN) && (o!=CAST||cflag))
ragge
1.1
198                 chkpun(p);
199
200         ifactions & (TYPL|TYPR) ){
201
ragge
1.22
202                 q = (actions&TYPL) ? p->n_left : p->n_right;
ragge
1.1
203
ragge
1.22
204                 p->n_type = q->n_type;
ragge
1.29
205                 p->n_df = q->n_df;
ragge
1.26
206                 p->n_sue = q->n_sue;
ragge
1.1
207                 }
208
209         ifactions & CVTL ) p = convertpCVTL );
210         ifactions & CVTR ) p = convertpCVTR );
211         ifactions & TYMATCH ) p = tymatch(p);
212         ifactions & PTMATCH ) p = ptmatch(p);
213
214         ifactions & OTHER ){
ragge
1.22
215                 l = p->n_left;
216                 r = p->n_right;
ragge
1.1
217
218                 switch(o){
219
220                 case NAME:
ragge
1.23
221                         sp = spname;
222                         if (sp->stype == UNDEF) {
223                                 uerror("%s undefined"sp->sname);
ragge
1.1
224                                 /* make p look reasonable */
ragge
1.26
225                                 p->n_type = INT;
226                                 p->n_sue = MKSUE(INT);
ragge
1.29
227                                 p->n_df = NULL;
ragge
1.23
228                                 p->n_sp = sp;
ragge
1.22
229                                 p->n_lval = 0;
ragge
1.23
230                                 defid(pSNULL);
ragge
1.1
231                                 break;
ragge
1.23
232                         }
ragge
1.22
233                         p->n_type = sp->stype;
ragge
1.29
234                         p->n_df = sp->sdf;
ragge
1.26
235                         p->n_sue = sp->ssue;
ragge
1.22
236                         p->n_lval = 0;
ragge
1.23
237                         p->n_sp = sp;
ragge
1.1
238                         /* special case: MOETY is really an ICON... */
ragge
1.23
239                         if (p->n_type == MOETY) {
240                                 p->n_sp = NULL;
241                                 p->n_lval = sp->soffset;
ragge
1.29
242                                 p->n_df = NULL;
ragge
1.22
243                                 p->n_type = ENUMTY;
244                                 p->n_op = ICON;
ragge
1.23
245                         }
ragge
1.1
246                         break;
247
248                 case STRING:
ragge
1.22
249                         p->n_op = NAME;
ragge
1.17
250 #ifdef CHAR_UNSIGNED
ragge
1.22
251                         p->n_type = UCHAR+ARY;
ragge
1.26
252                         p->n_sue = MKSUE(UCHAR);
ragge
1.17
253 #else
ragge
1.22
254                         p->n_type = CHAR+ARY;
ragge
1.26
255                         p->n_sue = MKSUE(CHAR);
ragge
1.17
256 #endif
ragge
1.22
257                         p->n_lval = 0;
ragge
1.23
258                         p->n_sp = NULL;
ragge
1.1
259                         break;
260
261                 case STREF:
262                         /* p->x turned into *(p+offset) */
263                         /* rhs must be a name; check correctness */
264
ragge
1.23
265                         /* Find member symbol struct */
266                         if (l->n_type != PTR+STRTY && l->n_type != PTR+UNIONTY){
267                                 uerror("struct or union required");
268                                 break;
269                         }
270
ragge
1.26
271                         if ((elem = l->n_sue->suelem) == NULL)
ragge
1.23
272                                 uerror("undefined struct or union");
273
274                         name = r->n_name;
ragge
1.26
275                         for (; *elem != NULLelem++) {
276                                 sp = *elem;
ragge
1.23
277                                 if (sp->sname == name)
278                                         break;
279                         }
ragge
1.26
280                         if (*elem == NULL)
ragge
1.23
281                                 uerror("member '%s' not declared"name);
282
283                         r->n_sp = sp;
284                         p = stref(p);
285                         break;
286
ragge
1.1
287                 case UNARY MUL:
ragge
1.41
288                         if (l->n_op == UNARY AND) {
289                                 nfree(p);
ragge
1.22
290                                 p = l->n_left;
ragge
1.41
291                                 nfree(l);
292                         }
ragge
1.22
293                         if( !ISPTR(l->n_type))uerror("illegal indirection");
294                         p->n_type = DECREF(l->n_type);
ragge
1.29
295                         p->n_df = l->n_df;
ragge
1.26
296                         p->n_sue = l->n_sue;
ragge
1.1
297                         break;
298
299                 case UNARY AND:
ragge
1.22
300                         switchl->n_op ){
ragge
1.1
301
302                         case UNARY MUL:
ragge
1.41
303                                 nfree(p);
ragge
1.22
304                                 p = l->n_left;
ragge
1.41
305                                 nfree(l);
ragge
1.1
306                         case NAME:
ragge
1.22
307                                 p->n_type = INCREFl->n_type );
ragge
1.29
308                                 p->n_df = l->n_df;
ragge
1.26
309                                 p->n_sue = l->n_sue;
ragge
1.1
310                                 break;
311
312                         case COMOP:
ragge
1.41
313                                 nfree(p);
ragge
1.22
314                                 lr = buildtreeUNARY ANDl->n_rightNIL );
315                                 p = buildtreeCOMOPl->n_leftlr );
ragge
1.41
316                                 nfree(l);
ragge
1.1
317                                 break;
318
319                         case QUEST:
ragge
1.22
320                                 lr = buildtreeUNARY ANDl->n_right->n_rightNIL );
321                                 ll = buildtreeUNARY ANDl->n_right->n_leftNIL );
ragge
1.41
322                                 nfree(p); nfree(l->n_right);
ragge
1.22
323                                 p = buildtreeQUESTl->n_leftbuildtreeCOLONlllr ) );
ragge
1.41
324                                 nfree(l);
ragge
1.1
325                                 break;
326
327                         default:
ragge
1.22
328                                 uerror("unacceptable operand of &: %d"l->n_op );
ragge
1.1
329                                 break;
330                                 }
331                         break;
332
333                 case LS:
ragge
1.50
334                 case RS:
ragge
1.1
335                 case ASG LS:
336                 case ASG RS:
ragge
1.50
337                         if(tsize(p->n_right->n_typep->n_right->n_dfp->n_right->n_sue) > SZINT)
ragge
1.26
338                                 p->n_right = r = makety(rINT0MKSUE(INT));
ragge
1.1
339                         break;
340
341                 case RETURN:
342                 case ASSIGN:
343                 case CAST:
344                         /* structure assignment */
345                         /* take the addresses of the two sides; then make an
ragge
1.2
346                          * operator using STASG and
347                          * the addresses of left and right */
ragge
1.1
348
349                         {
ragge
1.26
350                                 struct suedef *sue;
ragge
1.2
351                                 TWORD t;
ragge
1.29
352                                 union dimfun *d;
ragge
1.1
353
ragge
1.26
354                                 if (l->n_sue != r->n_sue)
355                                         uerror("assignment of different structures");
ragge
1.1
356
ragge
1.26
357                                 r = buildtree(UNARY ANDrNIL);
ragge
1.22
358                                 t = r->n_type;
ragge
1.29
359                                 d = r->n_df;
ragge
1.26
360                                 sue = r->n_sue;
ragge
1.1
361
ragge
1.28
362                                 l = block(STASGlrtdsue);
ragge
1.1
363
364                                 ifo == RETURN ){
ragge
1.41
365                                         nfree(p);
ragge
1.1
366                                         p = l;
367                                         break;
ragge
1.28
368                                 }
ragge
1.1
369
ragge
1.22
370                                 p->n_op = UNARY MUL;
371                                 p->n_left = l;
372                                 p->n_right = NIL;
ragge
1.1
373                                 break;
374                                 }
375                 case COLON:
376                         /* structure colon */
377
ragge
1.26
378                         if (l->n_sue != r->n_sue)
379                                 uerror"type clash in conditional" );
ragge
1.1
380                         break;
381
382                 case CALL:
ragge
1.45
383                         p->n_right = r = strargs(p->n_right);
ragge
1.1
384                 case UNARY CALL:
ragge
1.23
385                         if (!ISPTR(l->n_type))
386                                 uerror("illegal function");
ragge
1.22
387                         p->n_type = DECREF(l->n_type);
ragge
1.23
388                         if (!ISFTN(p->n_type))
389                                 uerror("illegal function");
390                         p->n_type = DECREF(p->n_type);
ragge
1.29
391                         p->n_df = l->n_df;
ragge
1.26
392                         p->n_sue = l->n_sue;
ragge
1.23
393                         if (l->n_op == UNARY AND && l->n_left->n_op == NAME &&
394                             l->n_left->n_sp != NULL && l->n_left->n_sp != NULL &&
395                             (l->n_left->n_sp->sclass == FORTRAN ||
396                             l->n_left->n_sp->sclass == UFORTRAN)) {
ragge
1.22
397                                 p->n_op += (FORTCALL-CALL);
ragge
1.23
398                         }
399                         if (p->n_type == STRTY || p->n_type == UNIONTY) {
ragge
1.1
400                                 /* function returning structure */
401                                 /*  make function really return ptr to str., with * */
402
ragge
1.22
403                                 p->n_op += STCALL-CALL;
ragge
1.23
404                                 p->n_type = INCREF(p->n_type);
405                                 p = buildtree(UNARY MULpNIL);
ragge
1.1
406
407                                 }
408                         break;
409
410                 default:
411                         cerror"other code %d"o );
412                         }
413
414                 }
415
ragge
1.11
416         /*
417          * Allow (void)0 casts.
418          * XXX - anything on the right side must be possible to cast.
419          * XXX - remove void types further on.
420          */
ragge
1.50
421         if (p->n_op == CAST && p->n_type == VOID &&
ragge
1.22
422             p->n_right->n_op == ICON)
ragge
1.50
423                 p->n_right->n_type = VOID;
ragge
1.11
424
ragge
1.1
425         ifactions & CVTO ) p = oconvert(p);
426         p = clocal(p);
427
ragge
1.30
428 #ifdef PCC_DEBUG
ragge
1.1
429         ifbdebug ) fwalkpeprint0 );
ragge
1.30
430 #endif
ragge
1.1
431
432         return(p);
433
434         }
435
436 NODE *
ragge
1.45
437 strargsp ) register NODE *p;  { /* rewrite structure flavored arguments */
ragge
1.1
438
ragge
1.45
439         ifp->n_op == CM ){
440                 p->n_left = strargsp->n_left );
441                 p->n_right = strargsp->n_right );
ragge
1.1
442                 returnp );
443                 }
444
ragge
1.22
445         ifp->n_type == STRTY || p->n_type == UNIONTY ){
ragge
1.29
446                 p = block(STARGpNILp->n_typep->n_dfp->n_sue);
ragge
1.22
447                 p->n_left = buildtreeUNARY ANDp->n_leftNIL );
ragge
1.1
448                 p = clocal(p);
449                 }
450         returnp );
ragge
1.2
451 }
ragge
1.1
452
ragge
1.2
453 /*
454  * apply the op o to the lval part of p; if binary, rhs is val
455  */
456 int
457 conval(NODE *pint oNODE *q)
458 {
ragge
1.1
459         int iu;
460         CONSZ val;
461
ragge
1.22
462         val = q->n_lval;
463         u = ISUNSIGNED(p->n_type) || ISUNSIGNED(q->n_type);
ragge
1.1
464         ifu && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE);
465
ragge
1.23
466         if (p->n_sp != NULL && q->n_sp != NULL)
467                 return(0);
468         if (q->n_sp != NULL && o != PLUS)
469                 return(0);
470         if (p->n_sp != NULL && o != PLUS && o != MINUS)
471                 return(0);
ragge
1.1
472
473         switcho ){
474
475         case PLUS:
ragge
1.22
476                 p->n_lval += val;
ragge
1.23
477                 if (p->n_sp == NULL) {
ragge
1.22
478                         p->n_rval = q->n_rval;
479                         p->n_type = q->n_type;
ragge
1.23
480                 }
ragge
1.1
481                 break;
482         case MINUS:
ragge
1.22
483                 p->n_lval -= val;
ragge
1.1
484                 break;
485         case MUL:
ragge
1.22
486                 p->n_lval *= val;
ragge
1.1
487                 break;
488         case DIV:
ragge
1.46
489                 if (val == 0)
490                         uerror("division by 0");
491                 else 
492                         p->n_lval /= val;
ragge
1.1
493                 break;
494         case MOD:
ragge
1.46
495                 if (val == 0)
496                         uerror("division by 0");
497                 else 
498                         p->n_lval %= val;
ragge
1.1
499                 break;
500         case AND:
ragge
1.22
501                 p->n_lval &= val;
ragge
1.1
502                 break;
503         case OR:
ragge
1.22
504                 p->n_lval |= val;
ragge
1.1
505                 break;
506         case ER:
ragge
1.22
507                 p->n_lval ^= val;
ragge
1.1
508                 break;
509         case LS:
510                 i = val;
ragge
1.22
511                 p->n_lval = p->n_lval << i;
ragge
1.1
512                 break;
513         case RS:
514                 i = val;
ragge
1.46
515                 p->n_lval = p->n_lval >> i;
ragge
1.1
516                 break;
517
518         case UNARY MINUS:
ragge
1.22
519                 p->n_lval = - p->n_lval;
ragge
1.1
520                 break;
521         case COMPL:
ragge
1.22
522                 p->n_lval = ~p->n_lval;
ragge
1.1
523                 break;
524         case NOT:
ragge
1.22
525                 p->n_lval = !p->n_lval;
ragge
1.1
526                 break;
527         case LT:
ragge
1.22
528                 p->n_lval = p->n_lval < val;
ragge
1.1
529                 break;
530         case LE:
ragge
1.22
531                 p->n_lval = p->n_lval <= val;
ragge
1.1
532                 break;
533         case GT:
ragge
1.22
534                 p->n_lval = p->n_lval > val;
ragge
1.1
535                 break;
536         case GE:
ragge
1.22
537                 p->n_lval = p->n_lval >= val;
ragge
1.1
538                 break;
539         case ULT:
ragge
1.46
540                 p->n_lval = (p->n_lval-val)<0;
ragge
1.1
541                 break;
542         case ULE:
ragge
1.46
543                 p->n_lval = (p->n_lval-val)<=0;
ragge
1.1
544                 break;
545         case UGT:
ragge
1.46
546                 p->n_lval = (p->n_lval-val)>=0;
ragge
1.1
547                 break;
548         case UGE:
ragge
1.46
549                 p->n_lval = (p->n_lval-val)>0;
ragge
1.1
550                 break;
551         case EQ:
ragge
1.22
552                 p->n_lval = p->n_lval == val;
ragge
1.1
553                 break;
554         case NE:
ragge
1.22
555                 p->n_lval = p->n_lval != val;
ragge
1.1
556                 break;
557         default:
558                 return(0);
559                 }
560         return(1);
561         }
562
ragge
1.7
563 /*
564  * Checks p for the existance of a pun.  This is called when the op of p
565  * is ASSIGN, RETURN, CAST, COLON, or relational.
566  * One case is when enumerations are used: this applies only to lint.
567  * In the other case, one operand is a pointer, the other integer type
568  * we check that this integer is in fact a constant zero...
569  * in the case of ASSIGN, any assignment of pointer to integer is illegal
570  * this falls out, because the LHS is never 0.
571  */
ragge
1.2
572 void
ragge
1.7
573 chkpun(NODE *p)
574 {
ragge
1.29
575         union dimfun *d1, *d2;
ragge
1.2
576         NODE *q;
ragge
1.47
577         int t1t2;
ragge
1.1
578
ragge
1.22
579         t1 = p->n_left->n_type;
580         t2 = p->n_right->n_type;
ragge
1.1
581
ragge
1.7
582         /* check for enumerations */
583         if (t1==ENUMTY || t2==ENUMTY) {
ragge
1.47
584                 iflogopp->n_op ) && p->n_op != EQ && p->n_op != NE ) {
585                         uerror"comparison of enums" );
586                         return;
587                         }
ragge
1.7
588                 if (t1==ENUMTY && t2==ENUMTY) {
ragge
1.26
589                         if (p->n_left->n_sue!=p->n_right->n_sue)
ragge
1.7
590                                 werror("enumeration type clash, "
ragge
1.47
591                                     "operator %s"opst[p->n_op]);
ragge
1.1
592                         return;
593                 }
ragge
1.7
594         }
ragge
1.1
595
ragge
1.47
596         ifISPTR(t1) || ISARY(t1) ) q = p->n_right;
597         else q = p->n_left;
ragge
1.1
598
ragge
1.47
599         if ( !ISPTR(q->n_type) && !ISARY(q->n_type) ){
ragge
1.22
600                 if (q->n_op != ICON || q->n_lval != 0)
ragge
1.47
601                         werror("illegal combination of pointer and integer");
602         } else {
603                 d1 = p->n_left->n_df;
604                 d2 = p->n_right->n_df;
605                 for (;;) {
606                         ift1 == t2 ) {;
607                                 if (p->n_left->n_sue != p->n_right->n_sue) {
608                                         werror("illegal structure pointer combination");
609                                 }
ragge
1.1
610                                 return;
ragge
1.5
611                         }
ragge
1.47
612                         if (ISARY(t1) || ISPTR(t1) ) {
613                                 if( !ISARY(t2) && !ISPTR(t2) ) break;
614                                 if (ISARY(t1) && ISARY(t2) && d1->ddim != d2->ddim) {
615                                         werror("illegal array size combination");
616                                         return;
617                                 }
618                                 ifISARY(t1) ) ++d1;
619                                 ifISARY(t2) ) ++d2; ++d2;
620                         } else if (ISFTN(t1)) {
621                                 if (chkftn(d1->dfund2->dfun)) {
622                                         werror("illegal function "
623                                             "pointer combination");
624                                         return;
625                                 }
626                                 ++d1;
627                                 ++d2;
628                         } else break;
629                         t1 = DECREF(t1);
630                         t2 = DECREF(t2);
631                 }
632                 werror("illegal pointer combination");
ragge
1.1
633         }
ragge
1.5
634 }
ragge
1.1
635
636 NODE *
ragge
1.10
637 stref(NODE *p)
638 {
ragge
1.41
639         NODE *r;
ragge
1.26
640         struct suedef *sue;
ragge
1.29
641         union dimfun *d;
ragge
1.1
642         TWORD t;
ragge
1.49
643         int dsc;
ragge
1.1
644         OFFSZ off;
645         register struct symtab *q;
646
647         /* make p->x */
648         /* this is also used to reference automatic variables */
649
ragge
1.23
650         q = p->n_right->n_sp;
ragge
1.41
651         nfree(p->n_right);
652         r = p->n_left;
653         nfree(p);
654         p = pconvert(r);
ragge
1.1
655
656         /* make p look like ptr to x */
657
ragge
1.22
658         if (!ISPTR(p->n_type))
659                 p->n_type = PTR+UNIONTY;
ragge
1.1
660
ragge
1.10
661         t = INCREF(q->stype);
ragge
1.29
662         d = q->sdf;
ragge
1.26
663         sue = q->ssue;
ragge
1.1
664
ragge
1.26
665         p = makety(ptdsue);
ragge
1.1
666
667         /* compute the offset to be added */
668
ragge
1.23
669         off = q->soffset;
ragge
1.1
670         dsc = q->sclass;
671
ragge
1.49
672         if (dsc & FIELD) {  /* make fields look like ints */
673                 off = (off/ALINT)*ALINT;
ragge
1.26
674                 sue = MKSUE(INT);
ragge
1.10
675         }
676         if (off != 0)
ragge
1.26
677                 p = clocal(block(PLUSpoffcon(offtdsue), tdsue));
ragge
1.1
678
ragge
1.10
679         p = buildtree(UNARY MULpNIL);
ragge
1.1
680
681         /* if field, build field info */
682
ragge
1.10
683         if (dsc & FIELD) {
ragge
1.26
684                 p = block(FLDpNILq->stype0q->ssue);
ragge
1.49
685                 p->n_rval = PKFIELD(dsc&FLDSIZq->soffset%ALINT);
ragge
1.10
686         }
ragge
1.1
687
ragge
1.19
688         p = clocal(p);
689         return p;
ragge
1.10
690 }
ragge
1.1
691
ragge
1.2
692 int
ragge
1.1
693 notlval(pregister NODE *p; {
694
695         /* return 0 if p an lvalue, 1 otherwise */
696
697         again:
698
ragge
1.22
699         switchp->n_op ){
ragge
1.1
700
701         case FLD:
ragge
1.22
702                 p = p->n_left;
ragge
1.1
703                 goto again;
704
705         case NAME:
706         case OREG:
ragge
1.49
707         case UNARY MUL:
ragge
1.22
708                 ifISARY(p->n_type) || ISFTN(p->n_type) ) return(1);
ragge
1.1
709         case REG:
710                 return(0);
711
712         default:
713                 return(1);
714
715                 }
716
717         }
ragge
1.23
718 /* make a constant node with value i */
ragge
1.1
719 NODE *
ragge
1.23
720 bcon(int i)
721 {
ragge
1.1
722         register NODE *p;
723
ragge
1.26
724         p = block(ICONNILNILINT0MKSUE(INT));
ragge
1.22
725         p->n_lval = i;
ragge
1.23
726         p->n_sp = NULL;
727         return(clocal(p));
728 }
ragge
1.1
729
730 NODE *
ragge
1.10
731 bpsize(NODE *p)
732 {
ragge
1.29
733         return(offcon(psize(p), p->n_typep->n_dfp->n_sue));
ragge
1.10
734 }
ragge
1.1
735
ragge
1.10
736 /*
737  * p is a node of type pointer; psize returns the
738  * size of the thing pointed to
739  */
ragge
1.1
740 OFFSZ
ragge
1.10
741 psize(NODE *p)
742 {
743
ragge
1.22
744         if (!ISPTR(p->n_type)) {
ragge
1.10
745                 uerror("pointer required");
746                 return(SZINT);
747         }
ragge
1.1
748         /* note: no pointers to fields */
ragge
1.29
749         return(tsize(DECREF(p->n_type), p->n_dfp->n_sue));
ragge
1.10
750 }
ragge
1.1
751
ragge
1.10
752 /*
753  * convert an operand of p
754  * f is either CVTL or CVTR
755  * operand has type int, and is converted by the size of the other side
756  */
ragge
1.1
757 NODE *
ragge
1.10
758 convert(NODE *pint f)
759 {
760         NODE *q, *r, *s;
ragge
1.1
761
ragge
1.22
762         q = (f == CVTL) ? p->n_left : p->n_right;
ragge
1.1
763
ragge
1.22
764         s = bpsize(f == CVTL ? p->n_right : p->n_left);
ragge
1.26
765         r = block(PMCONVqsINT0MKSUE(INT));
ragge
1.1
766         r = clocal(r);
ragge
1.13
767         /*
768          * Indexing is only allowed with integer arguments, so insert
769          * SCONV here if arg is not an integer.
770          * XXX - complain?
771          */
ragge
1.22
772         if (r->n_type != INT)
ragge
1.26
773                 r = clocal(block(SCONVrNILINT0MKSUE(INT)));
ragge
1.10
774         if (f == CVTL)
ragge
1.22
775                 p->n_left = r;
ragge
1.1
776         else
ragge
1.22
777                 p->n_right = r;
ragge
1.1
778         return(p);
ragge
1.10
779 }
ragge
1.1
780
ragge
1.2
781 void
ragge
1.1
782 econvertp ) register NODE *p; {
783
784         /* change enums to ints, or appropriate types */
785
786         register TWORD ty;
787
ragge
1.22
788         if( (ty=BTYPE(p->n_type)) == ENUMTY || ty == MOETY ) {
ragge
1.26
789                 if (p->n_sue->suesize == SZCHAR)
ragge
1.6
790                         ty = CHAR;
ragge
1.26
791                 else if (p->n_sue->suesize == SZINT)
ragge
1.6
792                         ty = INT;
ragge
1.26
793                 else if (p->n_sue->suesize == SZSHORT)
ragge
1.6
794                         ty = SHORT;
ragge
1.26
795                 else if (p->n_sue->suesize == SZLONGLONG)
ragge
1.6
796                         ty = LONGLONG;
797                 else
798                         ty = LONG;
799                 ty = ctype(ty);
ragge
1.26
800                 p->n_sue = MKSUE(ty);
ragge
1.22
801                 MODTYPE(p->n_type,ty);
802                 if (p->n_op == ICON && ty != LONG && ty != LONGLONG)
ragge
1.26
803                         p->n_type = INTp->n_sue = MKSUE(INT);
ragge
1.1
804         }
ragge
1.26
805 }
ragge
1.1
806
807 NODE *
808 pconvertp ) register NODE *p; {
809
810         /* if p should be changed into a pointer, do so */
811
ragge
1.22
812         ifISARYp->n_type) ){
813                 p->n_type = DECREFp->n_type );
ragge
1.29
814                 ++p->n_df;
ragge
1.1
815                 returnbuildtreeUNARY ANDpNIL ) );
ragge
1.28
816         }
ragge
1.22
817         ifISFTNp->n_type) )
ragge
1.1
818                 returnbuildtreeUNARY ANDpNIL ) );
819
820         returnp );
821         }
822
823 NODE *
824 oconvert(pregister NODE *p; {
825         /* convert the result itself: used for pointer and unsigned */
826
ragge
1.22
827         switch(p->n_op) {
ragge
1.1
828
829         case LE:
830         case LT:
831         case GE:
832         case GT:
ragge
1.22
833                 ifISUNSIGNED(p->n_left->n_type) || ISUNSIGNED(p->n_right->n_type) )  p->n_op += (ULE-LE);
ragge
1.1
834         case EQ:
835         case NE:
836                 returnp );
837
838         case MINUS:
839                 return(  clocalblockPVCONV,
ragge
1.26
840                         pbpsize(p->n_left), INT0MKSUE(INT))));
ragge
1.1
841                 }
842
ragge
1.22
843         cerror"illegal oconvert: %d"p->n_op );
ragge
1.1
844
845         return(p);
846         }