/* Copyright 1982, 1983 Alcyon Corporation 8716 Production Ave. San Diego, Ca. 92121 */ /** * alignment, node type altering routines, dimension table allocating * routine, and routines to determine elements actual size **/ #include "parser.h" #define DTSIZE 077 /*data size in bytes*/ char dinfo[]; /* dalloc - dimension table allocation*/ /* Allocates an entry in the dimension table.*/ dalloc(dimsize) /* returns ptr to dimension allocated*/ long dimsize; /* dimension size [vlh] 3.4 i=>l*/ { register short i; if( (i=cdp++) >= DSIZE-1 ) ferror("dimension table overflow"); dtab[i] = dimsize; return(i); } /* addsp - add special type to special type info*/ /* Takes given special type and adds it into the special type field.*/ addsp(type,nsptype) /* returns resulting type*/ int type; /* old type field*/ int nsptype; /* special type to be added*/ { register short dtype; dtype = BTYPE(type); type &= (~TYPE); if(type & (0xc000 >> SUTYPLEN)) /* [vlh] 4.3, top type field full */ error("arrays limited to five dimensions"); else type <<= SUTYPLEN; return( type | SUPTYPE(nsptype) | dtype ); } /* delsp - delete one special type info field from special type info*/ /* Takes given special type field and deletes least sign.*/ delsp(type) /* returns resulting type*/ int type; /* old special type*/ { register short dtype; dtype = BTYPE(type); type &= (~(ALLTYPE)); return( (type>>SUTYPLEN) | dtype ); } /* * revsp - reverse special type info * This allows for the processing of the super-type info in * the reverse order, which is necessary for initializations. */ revsp(type) /* returns reversed type info*/ int type; /* type to reverse*/ { register short t; for( t = BTYPE(type); SUPTYPE(type) != 0; type = delsp(type) ) t = addsp(t,type); return(t); } /* falign - handle bit field alignments*/ falign(type,flen,offset) /* returns number of bytes padded*/ int type; /* data type*/ int flen; /* field length*/ int offset; /* current structure offset */ { register short off; if( flen <= 0 ) { error("invalid field size"); flen = 0; } switch( type ) { case INT: case UNSIGNED: if( flen > BITSPWORD ) error("field overflows word"); if((flen+boffset) > BITSPWORD) off = CHRSPWORD; else off = (offset & 1); /* 1 if odd, 0 if even */ break; case CHAR: case UCHAR: if( flen > BITSPCHAR ) error("field overflows byte"); off = ((flen+boffset) > BITSPCHAR ); break; default: error("invalid field type description"); return(0); } if( off ) boffset = 0; boffset += flen; return(off); } /* salign - structure alignment*/ salign(type,offset) /* returns bytes of padding*/ int type; /* data type to align*/ int offset; /* current structure offset*/ { register short off; off = offset; if( boffset ) { /*remaining bit fields, flush 'em*/ off += (boffset+(BITSPCHAR-1))/BITSPCHAR; boffset = 0; } while( ISARRAY(type) ) /*get base type*/ type = delsp(type); if( type != CHAR ) /*need word boundary*/ off = WALIGN(off); return( off - offset ); } /* delspchk - delete one special reference and check if non-zero*/ delspchk(type) /*returns new special type*/ int type; /* type to modify*/ { if(!(SUPTYPE(type))) error("bad indirection"); return( delsp(type) ); } /* dosizeof - return size of object ptd at by POINTER [vlh] 4.2 */ dosizeof(tp,bool) /* returns size of object in bytes*/ struct tnode *tp; /* POINTER to tree node*/ int bool; /* 1==>sizeof expr, 0==>other sizeof*/ { short size, type; struct tnode *lp, *rp; PUTEXPR(treedebug,"dosizeof",tp); if (NOTPOINTER(tp->t_type) || tp->t_op != ADD) size = dsize(tp->t_type, tp->t_dp, tp->t_ssp); else { lp = tp->t_left; rp = tp->t_right; while (lp->t_op == ADD) { rp = lp->t_right; lp = lp->t_left; } type = lp->t_type; if ((type&STRUCT)==STRUCT || (type&FRSTRUCT)==FRSTRUCT) size = dtab[lp->t_dp - 1] * dsize(rp->t_type,rp->t_dp,rp->t_ssp); else size = dtab[lp->t_dp - 1] * (dinfo[type&TYPE]&DTSIZE); #ifdef DEBUG if(treedebug) { printf("second case: rtype 0%o ltype 0%o ",rp->t_type,lp->t_type); printf("dtab %ld\n",dtab[lp->t_dp-1]); } #endif } if (bool) /* [vlh] 4.2 */ indecl = predecl; /* value previous to sizeof.... */ #ifdef DEBUG if(treedebug) { printf("rtype 0%o ltype 0%o ",rp->t_type,lp->t_type); printf("size %d, dtab %ld\n",size,dtab[lp->t_dp-1]); } #endif return(size); } /* psize - return size of object ptd at by POINTER*/ long /* [vlh] 3.4 short => long */ psize(tp) /* returns size of object in bytes*/ struct tnode *tp; /* POINTER to tree node*/ { if ( !(SUPTYPE(tp->t_type)) ) /* what case ??? */ return(1); return(dsize(delsp(tp->t_type),tp->t_dp,tp->t_ssp)); } /* dsize - returns size of data object in bytes*/ long /* [vlh] 3.4 */ dsize(type,dp,sp) /* returns number of bytes*/ int type; /* type of node*/ int dp; /* dimension POINTER*/ int sp; /* size POINTER if structure*/ { register long nel, size; nel = 1; if (ISARRAY(type)) { do { type = delsp(type); } while (ISARRAY(type)); nel = dtab[dp]; } if( ISFUNCTION(type) ) return(0); size = (ISPOINTER(type)) ? PTRSIZE : (type == STRUCT) ? dtab[sp] : dinfo[type]&DTSIZE; #ifdef DEBUG if(treedebug) { printf("size %ld ",size); printf("nel %ld ",nel); printf("dinfo[type=0%o] ==> %d\n",type,dinfo[type]&DTSIZE); } #endif if(!size) error("invalid data type"); return( size * nel ); } /* integral - checks operand for integral type*/ /* This checks for needing an integral operand.*/ integral(tp,atype) /* returns - none*/ struct tnode *tp; /* pointer to tree node*/ int atype; /* alternate type allowable*/ { register short type; type = tp->t_type; if( type != INT && type != UNSIGNED && type != CHAR && type != UCHAR && !SUPTYPE(type) && type != atype ) /* [vlh]4.2 was error: */ warning("integral type expected"); /* "invalid operand type" */ }