117746Sralph #ifndef lint 2*41145Smckusick static char *sccsid ="@(#)pftn.c 1.28 (Berkeley) 04/30/90"; 317746Sralph #endif lint 417746Sralph 518398Sralph # include "pass1.h" 613939Slinton 713939Slinton unsigned int offsz; 813939Slinton 924405Smckusick struct symtab *schain[MAXSCOPES]; /* sym chains for clearst */ 1024405Smckusick int chaintop; /* highest active entry */ 1124405Smckusick 1213939Slinton struct instk { 1313939Slinton int in_sz; /* size of array element */ 1413939Slinton int in_x; /* current index for structure member in structure initializations */ 1513939Slinton int in_n; /* number of initializations seen */ 1613939Slinton int in_s; /* sizoff */ 1713939Slinton int in_d; /* dimoff */ 1813939Slinton TWORD in_t; /* type */ 1913939Slinton int in_id; /* stab index */ 2013939Slinton int in_fl; /* flag which says if this level is controlled by {} */ 2113939Slinton OFFSZ in_off; /* offset of the beginning of this level */ 2213939Slinton } 2313939Slinton instack[10], 2413939Slinton *pstk; 2513939Slinton 2613939Slinton /* defines used for getting things off of the initialization stack */ 2713939Slinton 2813939Slinton 2913939Slinton struct symtab *relook(); 3013939Slinton 3113939Slinton 3213939Slinton int ddebug = 0; 3313939Slinton 3413939Slinton struct symtab * mknonuniq(); 3513939Slinton 3624405Smckusick defid( q, class ) register NODE *q; register int class; { 3713939Slinton register struct symtab *p; 3813939Slinton int idp; 3924405Smckusick register TWORD type; 4013939Slinton TWORD stp; 4124405Smckusick register int scl; 4213939Slinton int dsym, ddef; 4313939Slinton int slev, temp; 4413940Slinton int changed; 4513939Slinton 4613939Slinton if( q == NIL ) return; /* an error was detected */ 4713939Slinton 4813939Slinton if( q < node || q >= &node[TREESZ] ) cerror( "defid call" ); 4913939Slinton 5013939Slinton idp = q->tn.rval; 5113939Slinton 5213939Slinton if( idp < 0 ) cerror( "tyreduce" ); 5313939Slinton p = &stab[idp]; 5413939Slinton 5513939Slinton # ifndef BUG1 5613939Slinton if( ddebug ){ 5713939Slinton #ifndef FLEXNAMES 5813939Slinton printf( "defid( %.8s (%d), ", p->sname, idp ); 5913939Slinton #else 6013939Slinton printf( "defid( %s (%d), ", p->sname, idp ); 6113939Slinton #endif 6213939Slinton tprint( q->in.type ); 6313939Slinton printf( ", %s, (%d,%d) ), level %d\n", scnames(class), q->fn.cdim, q->fn.csiz, blevel ); 6413939Slinton } 6513939Slinton # endif 6613939Slinton 6713939Slinton fixtype( q, class ); 6813939Slinton 6913939Slinton type = q->in.type; 7013939Slinton class = fixclass( class, type ); 7113939Slinton 7213939Slinton stp = p->stype; 7313939Slinton slev = p->slevel; 7413939Slinton 7513939Slinton # ifndef BUG1 7613939Slinton if( ddebug ){ 7713939Slinton printf( " modified to " ); 7813939Slinton tprint( type ); 7913939Slinton printf( ", %s\n", scnames(class) ); 8013939Slinton printf( " previous def'n: " ); 8113939Slinton tprint( stp ); 8213939Slinton printf( ", %s, (%d,%d) ), level %d\n", scnames(p->sclass), p->dimoff, p->sizoff, slev ); 8313939Slinton } 8413939Slinton # endif 8513939Slinton 8613939Slinton if( stp == FTN && p->sclass == SNULL )goto enter; 8732817Sdonn if( blevel==1 && stp!=FARG ) switch( class ){ 8813939Slinton 8913939Slinton default: 9013939Slinton #ifndef FLEXNAMES 9113939Slinton if(!(class&FIELD)) uerror( "declared argument %.8s is missing", p->sname ); 9213939Slinton #else 9313939Slinton if(!(class&FIELD)) uerror( "declared argument %s is missing", p->sname ); 9413939Slinton #endif 9513939Slinton case MOS: 9613939Slinton case STNAME: 9713939Slinton case MOU: 9813939Slinton case UNAME: 9913939Slinton case MOE: 10013939Slinton case ENAME: 10113939Slinton case TYPEDEF: 10213939Slinton ; 10313939Slinton } 10432817Sdonn if( stp == UNDEF|| stp == FARG ) goto enter; 10513939Slinton 10613939Slinton if( type != stp ) goto mismatch; 10732821Sdonn if( blevel > slev && (class == AUTO || class == REGISTER) ) 10832821Sdonn /* new scope */ 10932821Sdonn goto mismatch; 11032821Sdonn 11113939Slinton /* test (and possibly adjust) dimensions */ 11213939Slinton dsym = p->dimoff; 11313939Slinton ddef = q->fn.cdim; 11413940Slinton changed = 0; 11513939Slinton for( temp=type; temp&TMASK; temp = DECREF(temp) ){ 11613939Slinton if( ISARY(temp) ){ 11713940Slinton if (dimtab[dsym] == 0) { 11813940Slinton dimtab[dsym] = dimtab[ddef]; 11913940Slinton changed = 1; 12013940Slinton } 12113940Slinton else if (dimtab[ddef]!=0&&dimtab[dsym]!=dimtab[ddef]) { 12213939Slinton goto mismatch; 12313939Slinton } 12413939Slinton ++dsym; 12513939Slinton ++ddef; 12613939Slinton } 12713939Slinton } 12813939Slinton 12913940Slinton if (changed) { 13013940Slinton FIXDEF(p); 13113940Slinton } 13213940Slinton 13313939Slinton /* check that redeclarations are to the same structure */ 13413939Slinton if( (temp==STRTY||temp==UNIONTY||temp==ENUMTY) && p->sizoff != q->fn.csiz 13513939Slinton && class!=STNAME && class!=UNAME && class!=ENAME ){ 13613939Slinton goto mismatch; 13713939Slinton } 13813939Slinton 13913939Slinton scl = ( p->sclass ); 14013939Slinton 14113939Slinton # ifndef BUG1 14213939Slinton if( ddebug ){ 14313939Slinton printf( " previous class: %s\n", scnames(scl) ); 14413939Slinton } 14513939Slinton # endif 14613939Slinton 14713939Slinton if( class&FIELD ){ 14813939Slinton /* redefinition */ 14913939Slinton if( !falloc( p, class&FLDSIZ, 1, NIL ) ) { 15013939Slinton /* successful allocation */ 15113939Slinton psave( idp ); 15213939Slinton return; 15313939Slinton } 15413939Slinton /* blew it: resume at end of switch... */ 15513939Slinton } 15613939Slinton 15713939Slinton else switch( class ){ 15813939Slinton 15913939Slinton case EXTERN: 16013939Slinton switch( scl ){ 16113939Slinton case STATIC: 16213939Slinton case USTATIC: 16313939Slinton if( slev==0 ) return; 16413939Slinton break; 16513939Slinton case EXTDEF: 16613939Slinton case EXTERN: 16713939Slinton case FORTRAN: 16813939Slinton case UFORTRAN: 16913939Slinton return; 17013939Slinton } 17113939Slinton break; 17213939Slinton 17313939Slinton case STATIC: 17413939Slinton if( scl==USTATIC || (scl==EXTERN && blevel==0) ){ 17513939Slinton p->sclass = STATIC; 17613939Slinton if( ISFTN(type) ) curftn = idp; 17713939Slinton return; 17813939Slinton } 17913939Slinton break; 18013939Slinton 18113939Slinton case USTATIC: 18213939Slinton if( scl==STATIC || scl==USTATIC ) return; 18313939Slinton break; 18413939Slinton 18513939Slinton case LABEL: 18613939Slinton if( scl == ULABEL ){ 18713939Slinton p->sclass = LABEL; 18813939Slinton deflab( p->offset ); 18913939Slinton return; 19013939Slinton } 19113939Slinton break; 19213939Slinton 19313939Slinton case TYPEDEF: 19413939Slinton if( scl == class ) return; 19513939Slinton break; 19613939Slinton 19713939Slinton case UFORTRAN: 19813939Slinton if( scl == UFORTRAN || scl == FORTRAN ) return; 19913939Slinton break; 20013939Slinton 20113939Slinton case FORTRAN: 20213939Slinton if( scl == UFORTRAN ){ 20313939Slinton p->sclass = FORTRAN; 20413939Slinton if( ISFTN(type) ) curftn = idp; 20513939Slinton return; 20613939Slinton } 20713939Slinton break; 20813939Slinton 20913939Slinton case MOU: 21013939Slinton case MOS: 21113939Slinton if( scl == class ) { 21213939Slinton if( oalloc( p, &strucoff ) ) break; 21313939Slinton if( class == MOU ) strucoff = 0; 21413939Slinton psave( idp ); 21513939Slinton return; 21613939Slinton } 21713939Slinton break; 21813939Slinton 21913939Slinton case MOE: 22013939Slinton if( scl == class ){ 22113939Slinton if( p->offset!= strucoff++ ) break; 22213939Slinton psave( idp ); 22313939Slinton } 22413939Slinton break; 22513939Slinton 22613939Slinton case EXTDEF: 22713939Slinton if( scl == EXTERN ) { 22813939Slinton p->sclass = EXTDEF; 22913939Slinton if( ISFTN(type) ) curftn = idp; 23013939Slinton return; 23113939Slinton } 23213939Slinton break; 23313939Slinton 23413939Slinton case STNAME: 23513939Slinton case UNAME: 23613939Slinton case ENAME: 23713939Slinton if( scl != class ) break; 23813939Slinton if( dimtab[p->sizoff] == 0 ) return; /* previous entry just a mention */ 23913939Slinton break; 24013939Slinton 24113939Slinton case ULABEL: 24213939Slinton if( scl == LABEL || scl == ULABEL ) return; 24313939Slinton case PARAM: 24413939Slinton case AUTO: 24513939Slinton case REGISTER: 24613939Slinton ; /* mismatch.. */ 24713939Slinton 24813939Slinton } 24913939Slinton 25013939Slinton mismatch: 25113939Slinton /* allow nonunique structure/union member names */ 25213939Slinton 25313939Slinton if( class==MOU || class==MOS || class & FIELD ){/* make a new entry */ 25424405Smckusick register int *memp; 25513939Slinton p->sflags |= SNONUNIQ; /* old entry is nonunique */ 25613939Slinton /* determine if name has occurred in this structure/union */ 25717981Sralph if (paramno > 0) for( memp = ¶mstk[paramno-1]; 25813939Slinton /* while */ *memp>=0 && stab[*memp].sclass != STNAME 25913939Slinton && stab[*memp].sclass != UNAME; 26017981Sralph /* iterate */ --memp){ char *cname, *oname; 26132817Sdonn if( stab[*memp].sflags & SNONUNIQ ){ 26213939Slinton cname=p->sname; 26313939Slinton oname=stab[*memp].sname; 26413939Slinton #ifndef FLEXNAMES 26532817Sdonn for(temp=1; temp<=NCHNAM; ++temp){ 26613939Slinton if(*cname++ != *oname)goto diff; 26713939Slinton if(!*oname++)break; 26813939Slinton } 26913939Slinton #else 27013939Slinton if (cname != oname) goto diff; 27113939Slinton #endif 27213939Slinton uerror("redeclaration of: %s",p->sname); 27313939Slinton break; 27413939Slinton diff: continue; 27513939Slinton } 27613939Slinton } 27713939Slinton p = mknonuniq( &idp ); /* update p and idp to new entry */ 27813939Slinton goto enter; 27913939Slinton } 28013939Slinton if( blevel > slev && class != EXTERN && class != FORTRAN && 28113939Slinton class != UFORTRAN && !( class == LABEL && slev >= 2 ) ){ 28213939Slinton q->tn.rval = idp = hide( p ); 28313939Slinton p = &stab[idp]; 28413939Slinton goto enter; 28513939Slinton } 28613939Slinton #ifndef FLEXNAMES 28713939Slinton uerror( "redeclaration of %.8s", p->sname ); 28813939Slinton #else 28913939Slinton uerror( "redeclaration of %s", p->sname ); 29013939Slinton #endif 29113939Slinton if( class==EXTDEF && ISFTN(type) ) curftn = idp; 29213939Slinton return; 29313939Slinton 29413939Slinton enter: /* make a new entry */ 29513939Slinton 29613939Slinton # ifndef BUG1 29713939Slinton if( ddebug ) printf( " new entry made\n" ); 29813939Slinton # endif 29913939Slinton if( type == UNDEF ) uerror("void type for %s",p->sname); 30013939Slinton p->stype = type; 30113939Slinton p->sclass = class; 30213939Slinton p->slevel = blevel; 30313939Slinton p->offset = NOOFFSET; 30413939Slinton p->suse = lineno; 30513939Slinton if( class == STNAME || class == UNAME || class == ENAME ) { 30613939Slinton p->sizoff = curdim; 30713939Slinton dstash( 0 ); /* size */ 30813939Slinton dstash( -1 ); /* index to members of str or union */ 30913939Slinton dstash( ALSTRUCT ); /* alignment */ 31013939Slinton dstash( idp ); 31113939Slinton } 31213939Slinton else { 31313939Slinton switch( BTYPE(type) ){ 31413939Slinton case STRTY: 31513939Slinton case UNIONTY: 31613939Slinton case ENUMTY: 31713939Slinton p->sizoff = q->fn.csiz; 31813939Slinton break; 31913939Slinton default: 32013939Slinton p->sizoff = BTYPE(type); 32113939Slinton } 32213939Slinton } 32313939Slinton 32413939Slinton /* copy dimensions */ 32513939Slinton 32613939Slinton p->dimoff = q->fn.cdim; 32713939Slinton 32813939Slinton /* allocate offsets */ 32913939Slinton if( class&FIELD ){ 33032817Sdonn (void) falloc( p, class&FLDSIZ, 0, NIL ); /* new entry */ 33113939Slinton psave( idp ); 33213939Slinton } 33313939Slinton else switch( class ){ 33413939Slinton 33513939Slinton case AUTO: 33632817Sdonn (void) oalloc( p, &autooff ); 33713939Slinton break; 33813939Slinton case STATIC: 33913939Slinton case EXTDEF: 34013939Slinton p->offset = getlab(); 34113939Slinton if( ISFTN(type) ) curftn = idp; 34213939Slinton break; 34313939Slinton case ULABEL: 34413939Slinton case LABEL: 34513939Slinton p->offset = getlab(); 34613939Slinton p->slevel = 2; 34713939Slinton if( class == LABEL ){ 34832817Sdonn (void) locctr( PROG ); 34913939Slinton deflab( p->offset ); 35013939Slinton } 35113939Slinton break; 35213939Slinton 35313939Slinton case EXTERN: 35413939Slinton case UFORTRAN: 35513939Slinton case FORTRAN: 35613939Slinton p->offset = getlab(); 35713939Slinton p->slevel = 0; 35813939Slinton break; 35913939Slinton case MOU: 36013939Slinton case MOS: 36132817Sdonn (void) oalloc( p, &strucoff ); 36213939Slinton if( class == MOU ) strucoff = 0; 36313939Slinton psave( idp ); 36413939Slinton break; 36513939Slinton 36613939Slinton case MOE: 36713939Slinton p->offset = strucoff++; 36813939Slinton psave( idp ); 36913939Slinton break; 37013939Slinton case REGISTER: 37113939Slinton p->offset = regvar--; 37213939Slinton if( blevel == 1 ) p->sflags |= SSET; 37313939Slinton if( regvar < minrvar ) minrvar = regvar; 37413939Slinton break; 37513939Slinton } 37613939Slinton 37724405Smckusick { 37824405Smckusick register int l = p->slevel; 37924405Smckusick 38024405Smckusick if( l >= MAXSCOPES ) 38124405Smckusick cerror( "scopes nested too deep" ); 38224405Smckusick 38324405Smckusick p->snext = schain[l]; 38424405Smckusick schain[l] = p; 38524405Smckusick if( l >= chaintop ) 38624405Smckusick chaintop = l + 1; 38724405Smckusick } 38824405Smckusick 38913939Slinton /* user-supplied routine to fix up new definitions */ 39013939Slinton 39113939Slinton FIXDEF(p); 39213939Slinton 39313939Slinton # ifndef BUG1 39413939Slinton if( ddebug ) printf( " dimoff, sizoff, offset: %d, %d, %d\n", p->dimoff, p->sizoff, p->offset ); 39513939Slinton # endif 39613939Slinton 39713939Slinton } 39813939Slinton 39913939Slinton psave( i ){ 40013939Slinton if( paramno >= PARAMSZ ){ 40113939Slinton cerror( "parameter stack overflow"); 40213939Slinton } 40313939Slinton paramstk[ paramno++ ] = i; 40413939Slinton } 40513939Slinton 40613939Slinton ftnend(){ /* end of function */ 40732814Sdonn if( retlab != NOLAB && nerrors == 0 ){ /* inside a real function */ 40813939Slinton efcode(); 40913939Slinton } 41013939Slinton checkst(0); 41113939Slinton retstat = 0; 41213939Slinton tcheck(); 41313939Slinton curclass = SNULL; 41413939Slinton brklab = contlab = retlab = NOLAB; 41513939Slinton flostat = 0; 41613939Slinton if( nerrors == 0 ){ 41713939Slinton if( psavbc != & asavbc[0] ) cerror("bcsave error"); 41813939Slinton if( paramno != 0 ) cerror("parameter reset error"); 41913939Slinton if( swx != 0 ) cerror( "switch error"); 42013939Slinton } 42113939Slinton psavbc = &asavbc[0]; 42213939Slinton paramno = 0; 42313939Slinton autooff = AUTOINIT; 42413939Slinton minrvar = regvar = MAXRVAR; 42513939Slinton reached = 1; 42613939Slinton swx = 0; 42713939Slinton swp = swtab; 42832817Sdonn (void) locctr(DATA); 42913939Slinton } 43013939Slinton 43113939Slinton dclargs(){ 43213939Slinton register i, j; 43313939Slinton register struct symtab *p; 43413939Slinton register NODE *q; 43513939Slinton argoff = ARGINIT; 43613939Slinton # ifndef BUG1 43713939Slinton if( ddebug > 2) printf("dclargs()\n"); 43813939Slinton # endif 43913939Slinton for( i=0; i<paramno; ++i ){ 44013939Slinton if( (j = paramstk[i]) < 0 ) continue; 44113939Slinton p = &stab[j]; 44213939Slinton # ifndef BUG1 44313939Slinton if( ddebug > 2 ){ 44413939Slinton printf("\t%s (%d) ",p->sname, j); 44513939Slinton tprint(p->stype); 44613939Slinton printf("\n"); 44713939Slinton } 44813939Slinton # endif 44913939Slinton if( p->stype == FARG ) { 45013939Slinton q = block(FREE,NIL,NIL,INT,0,INT); 45113939Slinton q->tn.rval = j; 45213939Slinton defid( q, PARAM ); 45313939Slinton } 45413939Slinton FIXARG(p); /* local arg hook, eg. for sym. debugger */ 45513939Slinton oalloc( p, &argoff ); /* always set aside space, even for register arguments */ 45613939Slinton } 45713939Slinton cendarg(); 45832817Sdonn (void) locctr(PROG); 45913939Slinton defalign(ALINT); 46013939Slinton ftnno = getlab(); 46113939Slinton bfcode( paramstk, paramno ); 46213939Slinton paramno = 0; 46313939Slinton } 46413939Slinton 46513939Slinton NODE * 46613939Slinton rstruct( idn, soru ){ /* reference to a structure or union, with no definition */ 46713939Slinton register struct symtab *p; 46813939Slinton register NODE *q; 46913939Slinton p = &stab[idn]; 47013939Slinton switch( p->stype ){ 47113939Slinton 47213939Slinton case UNDEF: 47313939Slinton def: 47413939Slinton q = block( FREE, NIL, NIL, 0, 0, 0 ); 47513939Slinton q->tn.rval = idn; 47613939Slinton q->in.type = (soru&INSTRUCT) ? STRTY : ( (soru&INUNION) ? UNIONTY : ENUMTY ); 47713939Slinton defid( q, (soru&INSTRUCT) ? STNAME : ( (soru&INUNION) ? UNAME : ENAME ) ); 47813939Slinton break; 47913939Slinton 48013939Slinton case STRTY: 48113939Slinton if( soru & INSTRUCT ) break; 48213939Slinton goto def; 48313939Slinton 48413939Slinton case UNIONTY: 48513939Slinton if( soru & INUNION ) break; 48613939Slinton goto def; 48713939Slinton 48813939Slinton case ENUMTY: 48913939Slinton if( !(soru&(INUNION|INSTRUCT)) ) break; 49013939Slinton goto def; 49113939Slinton 49213939Slinton } 49313939Slinton stwart = instruct; 49413939Slinton return( mkty( p->stype, 0, p->sizoff ) ); 49513939Slinton } 49613939Slinton 49713939Slinton moedef( idn ){ 49813939Slinton register NODE *q; 49913939Slinton 50013939Slinton q = block( FREE, NIL, NIL, MOETY, 0, 0 ); 50113939Slinton q->tn.rval = idn; 50213939Slinton if( idn>=0 ) defid( q, MOE ); 50313939Slinton } 50413939Slinton 50513939Slinton bstruct( idn, soru ){ /* begining of structure or union declaration */ 50613939Slinton register NODE *q; 50713939Slinton 50813939Slinton psave( instruct ); 50913939Slinton psave( curclass ); 51013939Slinton psave( strucoff ); 51113939Slinton strucoff = 0; 51213939Slinton instruct = soru; 51313939Slinton q = block( FREE, NIL, NIL, 0, 0, 0 ); 51413939Slinton q->tn.rval = idn; 51513939Slinton if( instruct==INSTRUCT ){ 51613939Slinton curclass = MOS; 51713939Slinton q->in.type = STRTY; 51813939Slinton if( idn >= 0 ) defid( q, STNAME ); 51913939Slinton } 52013939Slinton else if( instruct == INUNION ) { 52113939Slinton curclass = MOU; 52213939Slinton q->in.type = UNIONTY; 52313939Slinton if( idn >= 0 ) defid( q, UNAME ); 52413939Slinton } 52513939Slinton else { /* enum */ 52613939Slinton curclass = MOE; 52713939Slinton q->in.type = ENUMTY; 52813939Slinton if( idn >= 0 ) defid( q, ENAME ); 52913939Slinton } 53013939Slinton psave( idn = q->tn.rval ); 53113939Slinton /* the "real" definition is where the members are seen */ 53213939Slinton if ( idn >= 0 ) stab[idn].suse = lineno; 53313939Slinton return( paramno-4 ); 53413939Slinton } 53513939Slinton 53613939Slinton NODE * 53713939Slinton dclstruct( oparam ){ 53813939Slinton register struct symtab *p; 53913939Slinton register i, al, sa, j, sz, szindex; 54013939Slinton register TWORD temp; 54113939Slinton register high, low; 54213939Slinton 54332817Sdonn /* paramstk contains: 54432817Sdonn paramstk[ oparam ] = previous instruct 54532817Sdonn paramstk[ oparam+1 ] = previous class 54613939Slinton paramstk[ oparam+2 ] = previous strucoff 54713939Slinton paramstk[ oparam+3 ] = structure name 54813939Slinton 54913939Slinton paramstk[ oparam+4, ... ] = member stab indices 55013939Slinton 55113939Slinton */ 55213939Slinton 55313939Slinton 55413939Slinton if( (i=paramstk[oparam+3]) < 0 ){ 55513939Slinton szindex = curdim; 55613939Slinton dstash( 0 ); /* size */ 55713939Slinton dstash( -1 ); /* index to member names */ 55813939Slinton dstash( ALSTRUCT ); /* alignment */ 55913939Slinton dstash( -lineno ); /* name of structure */ 56013939Slinton } 56113939Slinton else { 56213939Slinton szindex = stab[i].sizoff; 56313939Slinton } 56413939Slinton 56513939Slinton # ifndef BUG1 56613939Slinton if( ddebug ){ 56713939Slinton #ifndef FLEXNAMES 56813939Slinton printf( "dclstruct( %.8s ), szindex = %d\n", (i>=0)? stab[i].sname : "??", szindex ); 56913939Slinton #else 57013939Slinton printf( "dclstruct( %s ), szindex = %d\n", (i>=0)? stab[i].sname : "??", szindex ); 57113939Slinton #endif 57213939Slinton } 57313939Slinton # endif 57413939Slinton temp = (instruct&INSTRUCT)?STRTY:((instruct&INUNION)?UNIONTY:ENUMTY); 57513939Slinton stwart = instruct = paramstk[ oparam ]; 57613939Slinton curclass = paramstk[ oparam+1 ]; 57713939Slinton dimtab[ szindex+1 ] = curdim; 57813939Slinton al = ALSTRUCT; 57913939Slinton 58013939Slinton high = low = 0; 58113939Slinton 58213939Slinton for( i = oparam+4; i< paramno; ++i ){ 58313939Slinton dstash( j=paramstk[i] ); 58413939Slinton if( j<0 || j>= SYMTSZ ) cerror( "gummy structure member" ); 58513939Slinton p = &stab[j]; 58613939Slinton if( temp == ENUMTY ){ 58713939Slinton if( p->offset < low ) low = p->offset; 58813939Slinton if( p->offset > high ) high = p->offset; 58913939Slinton p->sizoff = szindex; 59013939Slinton continue; 59113939Slinton } 59213939Slinton sa = talign( p->stype, p->sizoff ); 59313939Slinton if( p->sclass & FIELD ){ 59413939Slinton sz = p->sclass&FLDSIZ; 59513939Slinton } 59613939Slinton else { 59713939Slinton sz = tsize( p->stype, p->dimoff, p->sizoff ); 59813939Slinton } 59913939Slinton if( sz == 0 ){ 60013939Slinton #ifndef FLEXNAMES 60113939Slinton werror( "illegal zero sized structure member: %.8s", p->sname ); 60213939Slinton #else 60313939Slinton werror( "illegal zero sized structure member: %s", p->sname ); 60413939Slinton #endif 60513939Slinton } 60613939Slinton if( sz > strucoff ) strucoff = sz; /* for use with unions */ 60713939Slinton SETOFF( al, sa ); 60813939Slinton /* set al, the alignment, to the lcm of the alignments of the members */ 60913939Slinton } 61013939Slinton dstash( -1 ); /* endmarker */ 61113939Slinton SETOFF( strucoff, al ); 61213939Slinton 61313939Slinton if( temp == ENUMTY ){ 61413939Slinton register TWORD ty; 61513939Slinton 61613939Slinton # ifdef ENUMSIZE 61713939Slinton ty = ENUMSIZE(high,low); 61813939Slinton # else 61913939Slinton if( (char)high == high && (char)low == low ) ty = ctype( CHAR ); 62013939Slinton else if( (short)high == high && (short)low == low ) ty = ctype( SHORT ); 62113939Slinton else ty = ctype(INT); 62213939Slinton #endif 62313939Slinton strucoff = tsize( ty, 0, (int)ty ); 62413939Slinton dimtab[ szindex+2 ] = al = talign( ty, (int)ty ); 62513939Slinton } 62613939Slinton 62713939Slinton if( strucoff == 0 ) uerror( "zero sized structure" ); 62813939Slinton dimtab[ szindex ] = strucoff; 62913939Slinton dimtab[ szindex+2 ] = al; 63013939Slinton dimtab[ szindex+3 ] = paramstk[ oparam+3 ]; /* name index */ 63113939Slinton 63213939Slinton FIXSTRUCT( szindex, oparam ); /* local hook, eg. for sym debugger */ 63313939Slinton # ifndef BUG1 63413939Slinton if( ddebug>1 ){ 63513939Slinton printf( "\tdimtab[%d,%d,%d] = %d,%d,%d\n", szindex,szindex+1,szindex+2, 63613939Slinton dimtab[szindex],dimtab[szindex+1],dimtab[szindex+2] ); 63713939Slinton for( i = dimtab[szindex+1]; dimtab[i] >= 0; ++i ){ 63813939Slinton #ifndef FLEXNAMES 63913939Slinton printf( "\tmember %.8s(%d)\n", stab[dimtab[i]].sname, dimtab[i] ); 64013939Slinton #else 64113939Slinton printf( "\tmember %s(%d)\n", stab[dimtab[i]].sname, dimtab[i] ); 64213939Slinton #endif 64313939Slinton } 64413939Slinton } 64513939Slinton # endif 64613939Slinton 64713939Slinton strucoff = paramstk[ oparam+2 ]; 64813939Slinton paramno = oparam; 64913939Slinton 65013939Slinton return( mkty( temp, 0, szindex ) ); 65113939Slinton } 65213939Slinton 65313939Slinton /* VARARGS */ 65413939Slinton yyerror( s ) char *s; { /* error printing routine in parser */ 65513939Slinton 65613939Slinton uerror( s ); 65713939Slinton 65813939Slinton } 65913939Slinton 66013939Slinton yyaccpt(){ 66113939Slinton ftnend(); 66213939Slinton } 66313939Slinton 66413939Slinton ftnarg( idn ) { 66513939Slinton switch( stab[idn].stype ){ 66613939Slinton 66713939Slinton case UNDEF: 66813939Slinton /* this parameter, entered at scan */ 66913939Slinton break; 67013939Slinton case FARG: 67113939Slinton #ifndef FLEXNAMES 67213939Slinton uerror("redeclaration of formal parameter, %.8s", 67313939Slinton #else 67413939Slinton uerror("redeclaration of formal parameter, %s", 67513939Slinton #endif 67613939Slinton stab[idn].sname); 67713939Slinton /* fall thru */ 67813939Slinton case FTN: 67913939Slinton /* the name of this function matches parm */ 68013939Slinton /* fall thru */ 68113939Slinton default: 68213939Slinton idn = hide( &stab[idn]); 68313939Slinton break; 68413939Slinton case TNULL: 68513939Slinton /* unused entry, fill it */ 68613939Slinton ; 68713939Slinton } 68813939Slinton stab[idn].stype = FARG; 68913939Slinton stab[idn].sclass = PARAM; 69013939Slinton psave( idn ); 69113939Slinton } 69213939Slinton 69313939Slinton talign( ty, s) register unsigned ty; register s; { 69413939Slinton /* compute the alignment of an object with type ty, sizeoff index s */ 69513939Slinton 69613939Slinton register i; 69713939Slinton if( s<0 && ty!=INT && ty!=CHAR && ty!=SHORT && ty!=UNSIGNED && ty!=UCHAR && ty!=USHORT 69813939Slinton #ifdef LONGFIELDS 69913939Slinton && ty!=LONG && ty!=ULONG 70013939Slinton #endif 70113939Slinton ){ 70213939Slinton return( fldal( ty ) ); 70313939Slinton } 70413939Slinton 70513939Slinton for( i=0; i<=(SZINT-BTSHIFT-1); i+=TSHIFT ){ 70613939Slinton switch( (ty>>i)&TMASK ){ 70713939Slinton 70813939Slinton case FTN: 709*41145Smckusick uerror( "can't assign to function" ); 710*41145Smckusick return( ALCHAR ); 71113939Slinton case PTR: 71213939Slinton return( ALPOINT ); 71313939Slinton case ARY: 71413939Slinton continue; 71513939Slinton case 0: 71613939Slinton break; 71713939Slinton } 71813939Slinton } 71913939Slinton 72013939Slinton switch( BTYPE(ty) ){ 72113939Slinton 72213939Slinton case UNIONTY: 72313939Slinton case ENUMTY: 72413939Slinton case STRTY: 72513939Slinton return( (unsigned int) dimtab[ s+2 ] ); 72613939Slinton case CHAR: 72713939Slinton case UCHAR: 72813939Slinton return( ALCHAR ); 72913939Slinton case FLOAT: 73013939Slinton return( ALFLOAT ); 73113939Slinton case DOUBLE: 73213939Slinton return( ALDOUBLE ); 73313939Slinton case LONG: 73413939Slinton case ULONG: 73513939Slinton return( ALLONG ); 73613939Slinton case SHORT: 73713939Slinton case USHORT: 73813939Slinton return( ALSHORT ); 73913939Slinton default: 74013939Slinton return( ALINT ); 74113939Slinton } 74213939Slinton } 74313939Slinton 74413939Slinton OFFSZ 74513939Slinton tsize( ty, d, s ) TWORD ty; { 74613939Slinton /* compute the size associated with type ty, 74713939Slinton dimoff d, and sizoff s */ 74813939Slinton /* BETTER NOT BE CALLED WHEN t, d, and s REFER TO A BIT FIELD... */ 74913939Slinton 75013939Slinton int i; 75113939Slinton OFFSZ mult; 75213939Slinton 75313939Slinton mult = 1; 75413939Slinton 75513939Slinton for( i=0; i<=(SZINT-BTSHIFT-1); i+=TSHIFT ){ 75613939Slinton switch( (ty>>i)&TMASK ){ 75713939Slinton 75813939Slinton case FTN: 75932819Sdonn /* cerror( "compiler takes size of function"); */ 76032819Sdonn uerror( "can't take size of function" ); 76132819Sdonn return( SZCHAR ); 76213939Slinton case PTR: 76313939Slinton return( SZPOINT * mult ); 76413939Slinton case ARY: 76513939Slinton mult *= (unsigned int) dimtab[ d++ ]; 76613939Slinton continue; 76713939Slinton case 0: 76813939Slinton break; 76913939Slinton 77013939Slinton } 77113939Slinton } 77213939Slinton 77313939Slinton if( dimtab[s]==0 ) { 77425749Sdonn if( ty == STRTY ) 77525749Sdonn uerror( "undefined structure" ); 77625749Sdonn else 77725749Sdonn uerror( "unknown size"); 77813939Slinton return( SZINT ); 77913939Slinton } 78013939Slinton return( (unsigned int) dimtab[ s ] * mult ); 78113939Slinton } 78213939Slinton 78313939Slinton inforce( n ) OFFSZ n; { /* force inoff to have the value n */ 78413939Slinton /* inoff is updated to have the value n */ 78513939Slinton OFFSZ wb; 78613939Slinton register rest; 78713939Slinton /* rest is used to do a lot of conversion to ints... */ 78813939Slinton 78913939Slinton if( inoff == n ) return; 79013939Slinton if( inoff > n ) { 79113939Slinton cerror( "initialization alignment error"); 79213939Slinton } 79313939Slinton 79413939Slinton wb = inoff; 79513939Slinton SETOFF( wb, SZINT ); 79613939Slinton 79713939Slinton /* wb now has the next higher word boundary */ 79813939Slinton 79913939Slinton if( wb >= n ){ /* in the same word */ 80013939Slinton rest = n - inoff; 80113939Slinton vfdzero( rest ); 80213939Slinton return; 80313939Slinton } 80413939Slinton 80513939Slinton /* otherwise, extend inoff to be word aligned */ 80613939Slinton 80713939Slinton rest = wb - inoff; 80813939Slinton vfdzero( rest ); 80913939Slinton 81013939Slinton /* now, skip full words until near to n */ 81113939Slinton 81213939Slinton rest = (n-inoff)/SZINT; 81313939Slinton zecode( rest ); 81413939Slinton 81513939Slinton /* now, the remainder of the last word */ 81613939Slinton 81713939Slinton rest = n-inoff; 81813939Slinton vfdzero( rest ); 81913939Slinton if( inoff != n ) cerror( "inoff error"); 82013939Slinton 82113939Slinton } 82213939Slinton 82313939Slinton vfdalign( n ){ /* make inoff have the offset the next alignment of n */ 82413939Slinton OFFSZ m; 82513939Slinton 82613939Slinton m = inoff; 82713939Slinton SETOFF( m, n ); 82813939Slinton inforce( m ); 82913939Slinton } 83013939Slinton 83113939Slinton 83213939Slinton int idebug = 0; 83313939Slinton 83413939Slinton int ibseen = 0; /* the number of } constructions which have been filled */ 83513939Slinton 83627247Sdonn int ifull = 0; /* 1 if all initializers have been seen */ 83727247Sdonn 83813939Slinton int iclass; /* storage class of thing being initialized */ 83913939Slinton 84013939Slinton int ilocctr = 0; /* location counter for current initialization */ 84113939Slinton 84213939Slinton beginit(curid){ 84313939Slinton /* beginning of initilization; set location ctr and set type */ 84413939Slinton register struct symtab *p; 84513939Slinton 84613939Slinton # ifndef BUG1 84713939Slinton if( idebug >= 3 ) printf( "beginit(), curid = %d\n", curid ); 84813939Slinton # endif 84913939Slinton 85013939Slinton p = &stab[curid]; 85113939Slinton 85213939Slinton iclass = p->sclass; 85313939Slinton if( curclass == EXTERN || curclass == FORTRAN ) iclass = EXTERN; 85413939Slinton switch( iclass ){ 85513939Slinton 85613939Slinton case UNAME: 85713939Slinton case EXTERN: 85813939Slinton return; 85913939Slinton case AUTO: 86013939Slinton case REGISTER: 86113939Slinton break; 86213939Slinton case EXTDEF: 86313939Slinton case STATIC: 86413939Slinton ilocctr = ISARY(p->stype)?ADATA:DATA; 86532814Sdonn if( nerrors == 0 ){ 86632817Sdonn (void) locctr( ilocctr ); 86732814Sdonn defalign( talign( p->stype, p->sizoff ) ); 86832814Sdonn defnam( p ); 86932814Sdonn } 87013939Slinton 87113939Slinton } 87213939Slinton 87313939Slinton inoff = 0; 87413939Slinton ibseen = 0; 87527247Sdonn ifull = 0; 87613939Slinton 87713939Slinton pstk = 0; 87813939Slinton 87913939Slinton instk( curid, p->stype, p->dimoff, p->sizoff, inoff ); 88013939Slinton 88113939Slinton } 88213939Slinton 88313939Slinton instk( id, t, d, s, off ) OFFSZ off; TWORD t; { 88413939Slinton /* make a new entry on the parameter stack to initialize id */ 88513939Slinton 88613939Slinton register struct symtab *p; 88713939Slinton 88813939Slinton for(;;){ 88913939Slinton # ifndef BUG1 89013939Slinton if( idebug ) printf( "instk((%d, %o,%d,%d, %d)\n", id, t, d, s, off ); 89113939Slinton # endif 89213939Slinton 89313939Slinton /* save information on the stack */ 89413939Slinton 89513939Slinton if( !pstk ) pstk = instack; 89613939Slinton else ++pstk; 89713939Slinton 89813939Slinton pstk->in_fl = 0; /* { flag */ 89913939Slinton pstk->in_id = id ; 90013939Slinton pstk->in_t = t ; 90113939Slinton pstk->in_d = d ; 90213939Slinton pstk->in_s = s ; 90313939Slinton pstk->in_n = 0; /* number seen */ 90413939Slinton pstk->in_x = t==STRTY ?dimtab[s+1] : 0 ; 90513939Slinton pstk->in_off = off; /* offset at the beginning of this element */ 90613939Slinton /* if t is an array, DECREF(t) can't be a field */ 90713939Slinton /* INS_sz has size of array elements, and -size for fields */ 90813939Slinton if( ISARY(t) ){ 90913939Slinton pstk->in_sz = tsize( DECREF(t), d+1, s ); 91013939Slinton } 91113939Slinton else if( stab[id].sclass & FIELD ){ 91213939Slinton pstk->in_sz = - ( stab[id].sclass & FLDSIZ ); 91313939Slinton } 91413939Slinton else { 91513939Slinton pstk->in_sz = 0; 91613939Slinton } 91713939Slinton 91813939Slinton if( (iclass==AUTO || iclass == REGISTER ) && 91913939Slinton (ISARY(t) || t==STRTY) ) uerror( "no automatic aggregate initialization" ); 92013939Slinton 92113939Slinton /* now, if this is not a scalar, put on another element */ 92213939Slinton 92313939Slinton if( ISARY(t) ){ 92413939Slinton t = DECREF(t); 92513939Slinton ++d; 92613939Slinton continue; 92713939Slinton } 92813939Slinton else if( t == STRTY ){ 92925749Sdonn if( dimtab[pstk->in_s] == 0 ){ 93025749Sdonn uerror( "can't initialize undefined structure" ); 93125749Sdonn iclass = -1; 93225749Sdonn return; 93325749Sdonn } 93413939Slinton id = dimtab[pstk->in_x]; 93513939Slinton p = &stab[id]; 93613939Slinton if( p->sclass != MOS && !(p->sclass&FIELD) ) cerror( "insane structure member list" ); 93713939Slinton t = p->stype; 93813939Slinton d = p->dimoff; 93913939Slinton s = p->sizoff; 94013939Slinton off += p->offset; 94113939Slinton continue; 94213939Slinton } 94313939Slinton else return; 94413939Slinton } 94513939Slinton } 94613939Slinton 94713939Slinton NODE * 94813939Slinton getstr(){ /* decide if the string is external or an initializer, and get the contents accordingly */ 94913939Slinton 95013939Slinton register l, temp; 95113939Slinton register NODE *p; 95213939Slinton 95313939Slinton if( (iclass==EXTDEF||iclass==STATIC) && (pstk->in_t == CHAR || pstk->in_t == UCHAR) && 95413939Slinton pstk!=instack && ISARY( pstk[-1].in_t ) ){ 95513939Slinton /* treat "abc" as { 'a', 'b', 'c', 0 } */ 95613939Slinton strflg = 1; 95713939Slinton ilbrace(); /* simulate { */ 95813939Slinton inforce( pstk->in_off ); 95913939Slinton /* if the array is inflexible (not top level), pass in the size and 96013939Slinton be prepared to throw away unwanted initializers */ 96113939Slinton lxstr((pstk-1)!=instack?dimtab[(pstk-1)->in_d]:0); /* get the contents */ 96213939Slinton irbrace(); /* simulate } */ 96313939Slinton return( NIL ); 96413939Slinton } 96513939Slinton else { /* make a label, and get the contents and stash them away */ 96613939Slinton if( iclass != SNULL ){ /* initializing */ 96713939Slinton /* fill out previous word, to permit pointer */ 96813939Slinton vfdalign( ALPOINT ); 96913939Slinton } 97013939Slinton temp = locctr( blevel==0?ISTRNG:STRNG ); /* set up location counter */ 97113939Slinton deflab( l = getlab() ); 97213939Slinton strflg = 0; 97313939Slinton lxstr(0); /* get the contents */ 97432817Sdonn (void) locctr( blevel==0?ilocctr:temp ); 97513939Slinton p = buildtree( STRING, NIL, NIL ); 97613939Slinton p->tn.rval = -l; 97713939Slinton return(p); 97813939Slinton } 97913939Slinton } 98013939Slinton 98113939Slinton putbyte( v ){ /* simulate byte v appearing in a list of integer values */ 98213939Slinton register NODE *p; 98313939Slinton p = bcon(v); 98413939Slinton incode( p, SZCHAR ); 98513939Slinton tfree( p ); 98613939Slinton gotscal(); 98713939Slinton } 98813939Slinton 98913939Slinton endinit(){ 99013939Slinton register TWORD t; 99113939Slinton register d, s, n, d1; 99213939Slinton 99313939Slinton # ifndef BUG1 99413939Slinton if( idebug ) printf( "endinit(), inoff = %d\n", inoff ); 99513939Slinton # endif 99613939Slinton 99713939Slinton switch( iclass ){ 99813939Slinton 99913939Slinton case EXTERN: 100013939Slinton case AUTO: 100113939Slinton case REGISTER: 100225749Sdonn case -1: 100313939Slinton return; 100413939Slinton } 100513939Slinton 100613939Slinton pstk = instack; 100713939Slinton 100813939Slinton t = pstk->in_t; 100913939Slinton d = pstk->in_d; 101013939Slinton s = pstk->in_s; 101113939Slinton n = pstk->in_n; 101213939Slinton 101313939Slinton if( ISARY(t) ){ 101413939Slinton d1 = dimtab[d]; 101513939Slinton 101613939Slinton vfdalign( pstk->in_sz ); /* fill out part of the last element, if needed */ 101713939Slinton n = inoff/pstk->in_sz; /* real number of initializers */ 101813939Slinton if( d1 >= n ){ 101913939Slinton /* once again, t is an array, so no fields */ 102013939Slinton inforce( tsize( t, d, s ) ); 102113939Slinton n = d1; 102213939Slinton } 102313939Slinton if( d1!=0 && d1!=n ) uerror( "too many initializers"); 102413939Slinton if( n==0 ) werror( "empty array declaration"); 102513939Slinton dimtab[d] = n; 102613942Slinton if( d1==0 ) FIXDEF(&stab[pstk->in_id]); 102713939Slinton } 102813939Slinton 102913939Slinton else if( t == STRTY || t == UNIONTY ){ 103013939Slinton /* clearly not fields either */ 103113939Slinton inforce( tsize( t, d, s ) ); 103213939Slinton } 103313939Slinton else if( n > 1 ) uerror( "bad scalar initialization"); 103413939Slinton /* this will never be called with a field element... */ 103513939Slinton else inforce( tsize(t,d,s) ); 103613939Slinton 103713939Slinton paramno = 0; 103813939Slinton vfdalign( AL_INIT ); 103913939Slinton inoff = 0; 104013939Slinton iclass = SNULL; 104113939Slinton 104213939Slinton } 104313939Slinton 104432818Sdonn fixinit(){ 104532818Sdonn /* called from the grammar if we must punt during initialization */ 104632818Sdonn /* stolen from endinit() */ 104732818Sdonn pstk = instack; 104832818Sdonn paramno = 0; 104932818Sdonn vfdalign( AL_INIT ); 105032818Sdonn inoff = 0; 105132818Sdonn iclass = SNULL; 105232818Sdonn } 105332818Sdonn 105413939Slinton doinit( p ) register NODE *p; { 105513939Slinton 105613939Slinton /* take care of generating a value for the initializer p */ 105713939Slinton /* inoff has the current offset (last bit written) 105813939Slinton in the current word being generated */ 105913939Slinton 106013939Slinton register sz, d, s; 106113939Slinton register TWORD t; 106217746Sralph int o; 106313939Slinton 106413939Slinton /* note: size of an individual initializer is assumed to fit into an int */ 106513939Slinton 106632814Sdonn if( iclass < 0 ) goto leave; 106713939Slinton if( iclass == EXTERN || iclass == UNAME ){ 106813939Slinton uerror( "cannot initialize extern or union" ); 106913939Slinton iclass = -1; 107013939Slinton goto leave; 107113939Slinton } 107213939Slinton 107313939Slinton if( iclass == AUTO || iclass == REGISTER ){ 107413939Slinton /* do the initialization and get out, without regard 107513939Slinton for filing out the variable with zeros, etc. */ 107613939Slinton bccode(); 107713939Slinton idname = pstk->in_id; 107813939Slinton p = buildtree( ASSIGN, buildtree( NAME, NIL, NIL ), p ); 107913939Slinton ecomp(p); 108013939Slinton return; 108113939Slinton } 108213939Slinton 108313939Slinton if( p == NIL ) return; /* for throwing away strings that have been turned into lists */ 108413939Slinton 108527247Sdonn if( ifull ){ 108627247Sdonn uerror( "too many initializers" ); 108727247Sdonn iclass = -1; 108827247Sdonn goto leave; 108927247Sdonn } 109013939Slinton if( ibseen ){ 109113939Slinton uerror( "} expected"); 109213939Slinton goto leave; 109313939Slinton } 109413939Slinton 109513939Slinton # ifndef BUG1 109613939Slinton if( idebug > 1 ) printf( "doinit(%o)\n", p ); 109713939Slinton # endif 109813939Slinton 109913939Slinton t = pstk->in_t; /* type required */ 110013939Slinton d = pstk->in_d; 110113939Slinton s = pstk->in_s; 110213939Slinton if( pstk->in_sz < 0 ){ /* bit field */ 110313939Slinton sz = -pstk->in_sz; 110413939Slinton } 110513939Slinton else { 110613939Slinton sz = tsize( t, d, s ); 110713939Slinton } 110813939Slinton 110913939Slinton inforce( pstk->in_off ); 111013939Slinton 111113939Slinton p = buildtree( ASSIGN, block( NAME, NIL,NIL, t, d, s ), p ); 111232824Sdonn #ifdef LINT 111332824Sdonn /* force lint to treat this like an assignment */ 111432824Sdonn ecode(p); 111532824Sdonn #endif 111613939Slinton p->in.left->in.op = FREE; 111713939Slinton p->in.left = p->in.right; 111813939Slinton p->in.right = NIL; 111913939Slinton p->in.left = optim( p->in.left ); 112017746Sralph o = p->in.left->in.op; 112117746Sralph if( o == UNARY AND ){ 112217746Sralph o = p->in.left->in.op = FREE; 112313939Slinton p->in.left = p->in.left->in.left; 112413939Slinton } 112513939Slinton p->in.op = INIT; 112613939Slinton 112713939Slinton if( sz < SZINT ){ /* special case: bit fields, etc. */ 112832815Sdonn if( o != ICON || p->in.left->tn.rval != NONAME ) 112932815Sdonn uerror( "illegal initialization" ); 113013939Slinton else incode( p->in.left, sz ); 113113939Slinton } 113217746Sralph else if( o == FCON ){ 113317746Sralph fincode( p->in.left->fpn.fval, sz ); 113413939Slinton } 113517746Sralph else if( o == DCON ){ 113617746Sralph fincode( p->in.left->dpn.dval, sz ); 113717746Sralph } 113813939Slinton else { 113916178Sralph p = optim(p); 114016178Sralph if( p->in.left->in.op != ICON ) uerror( "illegal initialization" ); 114116178Sralph else cinit( p, sz ); 114213939Slinton } 114313939Slinton 114413939Slinton gotscal(); 114513939Slinton 114613939Slinton leave: 114713939Slinton tfree(p); 114813939Slinton } 114913939Slinton 115013939Slinton gotscal(){ 115113939Slinton register t, ix; 115213939Slinton register n, id; 115313939Slinton struct symtab *p; 115413939Slinton OFFSZ temp; 115513939Slinton 115613939Slinton for( ; pstk > instack; ) { 115713939Slinton 115813939Slinton if( pstk->in_fl ) ++ibseen; 115913939Slinton 116013939Slinton --pstk; 116113939Slinton 116213939Slinton t = pstk->in_t; 116313939Slinton 116413939Slinton if( t == STRTY ){ 116513939Slinton ix = ++pstk->in_x; 116613939Slinton if( (id=dimtab[ix]) < 0 ) continue; 116713939Slinton 116813939Slinton /* otherwise, put next element on the stack */ 116913939Slinton 117013939Slinton p = &stab[id]; 117113939Slinton instk( id, p->stype, p->dimoff, p->sizoff, p->offset+pstk->in_off ); 117213939Slinton return; 117313939Slinton } 117413939Slinton else if( ISARY(t) ){ 117513939Slinton n = ++pstk->in_n; 117613939Slinton if( n >= dimtab[pstk->in_d] && pstk > instack ) continue; 117713939Slinton 117813939Slinton /* put the new element onto the stack */ 117913939Slinton 118013939Slinton temp = pstk->in_sz; 118113939Slinton instk( pstk->in_id, (TWORD)DECREF(pstk->in_t), pstk->in_d+1, pstk->in_s, 118213939Slinton pstk->in_off+n*temp ); 118313939Slinton return; 118413939Slinton } 118513939Slinton 118613939Slinton } 118727247Sdonn ifull = 1; 118813939Slinton } 118913939Slinton 119013939Slinton ilbrace(){ /* process an initializer's left brace */ 119113939Slinton register t; 119213939Slinton struct instk *temp; 119313939Slinton 119413939Slinton temp = pstk; 119513939Slinton 119613939Slinton for( ; pstk > instack; --pstk ){ 119713939Slinton 119813939Slinton t = pstk->in_t; 119913939Slinton if( t != STRTY && !ISARY(t) ) continue; /* not an aggregate */ 120013939Slinton if( pstk->in_fl ){ /* already associated with a { */ 120113939Slinton if( pstk->in_n ) uerror( "illegal {"); 120213939Slinton continue; 120313939Slinton } 120413939Slinton 120513939Slinton /* we have one ... */ 120613939Slinton pstk->in_fl = 1; 120713939Slinton break; 120813939Slinton } 120913939Slinton 121013939Slinton /* cannot find one */ 121113939Slinton /* ignore such right braces */ 121213939Slinton 121313939Slinton pstk = temp; 121413939Slinton } 121513939Slinton 121613939Slinton irbrace(){ 121713939Slinton /* called when a '}' is seen */ 121813939Slinton 121913939Slinton # ifndef BUG1 122013939Slinton if( idebug ) printf( "irbrace(): paramno = %d on entry\n", paramno ); 122113939Slinton # endif 122213939Slinton 122313939Slinton if( ibseen ) { 122413939Slinton --ibseen; 122513939Slinton return; 122613939Slinton } 122713939Slinton 122813939Slinton for( ; pstk > instack; --pstk ){ 122913939Slinton if( !pstk->in_fl ) continue; 123013939Slinton 123113939Slinton /* we have one now */ 123213939Slinton 123313939Slinton pstk->in_fl = 0; /* cancel { */ 123413939Slinton gotscal(); /* take it away... */ 123513939Slinton return; 123613939Slinton } 123713939Slinton 123813939Slinton /* these right braces match ignored left braces: throw out */ 123927247Sdonn ifull = 1; 124013939Slinton 124113939Slinton } 124213939Slinton 124313939Slinton upoff( size, alignment, poff ) register alignment, *poff; { 124413939Slinton /* update the offset pointed to by poff; return the 124513939Slinton /* offset of a value of size `size', alignment `alignment', 124613939Slinton /* given that off is increasing */ 124713939Slinton 124813939Slinton register off; 124913939Slinton 125013939Slinton off = *poff; 125113939Slinton SETOFF( off, alignment ); 125213939Slinton if( (offsz-off) < size ){ 125313939Slinton if( instruct!=INSTRUCT )cerror("too many local variables"); 125413939Slinton else cerror("Structure too large"); 125513939Slinton } 125613939Slinton *poff = off+size; 125713939Slinton return( off ); 125813939Slinton } 125913939Slinton 126013939Slinton oalloc( p, poff ) register struct symtab *p; register *poff; { 126113939Slinton /* allocate p with offset *poff, and update *poff */ 126213939Slinton register al, off, tsz; 126313939Slinton int noff; 126413939Slinton 126513939Slinton al = talign( p->stype, p->sizoff ); 126613939Slinton noff = off = *poff; 126713939Slinton tsz = tsize( p->stype, p->dimoff, p->sizoff ); 126813939Slinton #ifdef BACKAUTO 126913939Slinton if( p->sclass == AUTO ){ 127013939Slinton if( (offsz-off) < tsz ) cerror("too many local variables"); 127113939Slinton noff = off + tsz; 127213939Slinton SETOFF( noff, al ); 127313939Slinton off = -noff; 127413939Slinton } 127513939Slinton else 127613939Slinton #endif 127713939Slinton if( p->sclass == PARAM && ( tsz < SZINT ) ){ 127813939Slinton off = upoff( SZINT, ALINT, &noff ); 127913939Slinton # ifndef RTOLBYTES 128013939Slinton off = noff - tsz; 128113939Slinton #endif 128213939Slinton } 128313939Slinton else 128413939Slinton { 128513939Slinton off = upoff( tsz, al, &noff ); 128613939Slinton } 128713939Slinton 128813939Slinton if( p->sclass != REGISTER ){ /* in case we are allocating stack space for register arguments */ 128913939Slinton if( p->offset == NOOFFSET ) p->offset = off; 129013939Slinton else if( off != p->offset ) return(1); 129113939Slinton } 129213939Slinton 129313939Slinton *poff = noff; 129413939Slinton return(0); 129513939Slinton } 129613939Slinton 129713939Slinton falloc( p, w, new, pty ) register struct symtab *p; NODE *pty; { 129813939Slinton /* allocate a field of width w */ 129913939Slinton /* new is 0 if new entry, 1 if redefinition, -1 if alignment */ 130013939Slinton 130113939Slinton register al,sz,type; 130213939Slinton 130313939Slinton type = (new<0)? pty->in.type : p->stype; 130413939Slinton 130513939Slinton /* this must be fixed to use the current type in alignments */ 130613939Slinton switch( new<0?pty->in.type:p->stype ){ 130713939Slinton 130813939Slinton case ENUMTY: 130913939Slinton { 131013939Slinton int s; 131113939Slinton s = new<0 ? pty->fn.csiz : p->sizoff; 131213939Slinton al = dimtab[s+2]; 131313939Slinton sz = dimtab[s]; 131413939Slinton break; 131513939Slinton } 131613939Slinton 131713939Slinton case CHAR: 131813939Slinton case UCHAR: 131913939Slinton al = ALCHAR; 132013939Slinton sz = SZCHAR; 132113939Slinton break; 132213939Slinton 132313939Slinton case SHORT: 132413939Slinton case USHORT: 132513939Slinton al = ALSHORT; 132613939Slinton sz = SZSHORT; 132713939Slinton break; 132813939Slinton 132913939Slinton case INT: 133013939Slinton case UNSIGNED: 133113939Slinton al = ALINT; 133213939Slinton sz = SZINT; 133313939Slinton break; 133413939Slinton #ifdef LONGFIELDS 133513939Slinton 133613939Slinton case LONG: 133713939Slinton case ULONG: 133813939Slinton al = ALLONG; 133913939Slinton sz = SZLONG; 134013939Slinton break; 134113939Slinton #endif 134213939Slinton 134313939Slinton default: 134413939Slinton if( new < 0 ) { 134513939Slinton uerror( "illegal field type" ); 134613939Slinton al = ALINT; 134713939Slinton } 134813939Slinton else { 134913939Slinton al = fldal( p->stype ); 135013939Slinton sz =SZINT; 135113939Slinton } 135213939Slinton } 135313939Slinton 135413939Slinton if( w > sz ) { 135513939Slinton uerror( "field too big"); 135613939Slinton w = sz; 135713939Slinton } 135813939Slinton 135913939Slinton if( w == 0 ){ /* align only */ 136013939Slinton SETOFF( strucoff, al ); 136113939Slinton if( new >= 0 ) uerror( "zero size field"); 136213939Slinton return(0); 136313939Slinton } 136413939Slinton 136513939Slinton if( strucoff%al + w > sz ) SETOFF( strucoff, al ); 136613939Slinton if( new < 0 ) { 136713939Slinton if( (offsz-strucoff) < w ) 136813939Slinton cerror("structure too large"); 136913939Slinton strucoff += w; /* we know it will fit */ 137013939Slinton return(0); 137113939Slinton } 137213939Slinton 137313939Slinton /* establish the field */ 137413939Slinton 137513939Slinton if( new == 1 ) { /* previous definition */ 137613939Slinton if( p->offset != strucoff || p->sclass != (FIELD|w) ) return(1); 137713939Slinton } 137813939Slinton p->offset = strucoff; 137913939Slinton if( (offsz-strucoff) < w ) cerror("structure too large"); 138013939Slinton strucoff += w; 138113939Slinton p->stype = type; 138213939Slinton fldty( p ); 138313939Slinton return(0); 138413939Slinton } 138513939Slinton 138613939Slinton nidcl( p ) NODE *p; { /* handle unitialized declarations */ 138713939Slinton /* assumed to be not functions */ 138813939Slinton register class; 138913939Slinton register commflag; /* flag for labelled common declarations */ 139013939Slinton 139113939Slinton commflag = 0; 139213939Slinton 139313939Slinton /* compute class */ 139413939Slinton if( (class=curclass) == SNULL ){ 139513939Slinton if( blevel > 1 ) class = AUTO; 139613939Slinton else if( blevel != 0 || instruct ) cerror( "nidcl error" ); 139713939Slinton else { /* blevel = 0 */ 139813939Slinton class = noinit(); 139913939Slinton if( class == EXTERN ) commflag = 1; 140013939Slinton } 140113939Slinton } 140213939Slinton #ifdef LCOMM 140332817Sdonn /* hack so stab will come out as LCSYM rather than STSYM */ 140413939Slinton if (class == STATIC) { 140513939Slinton extern int stabLCSYM; 140613939Slinton stabLCSYM = 1; 140713939Slinton } 140813939Slinton #endif 140913939Slinton 141013939Slinton defid( p, class ); 141113939Slinton 141232816Sdonn /* if an array is not initialized, no empty dimension */ 141332820Sdonn if( class!=EXTERN && class!=TYPEDEF && 141432820Sdonn ISARY(p->in.type) && dimtab[p->fn.cdim]==0 ) 141532816Sdonn uerror("null storage definition"); 141632816Sdonn 141713939Slinton #ifndef LCOMM 141824405Smckusick if( class==EXTDEF || class==STATIC ) 141913939Slinton #else 142013939Slinton if (class==STATIC) { 142113939Slinton register struct symtab *s = &stab[p->tn.rval]; 142213939Slinton extern int stabLCSYM; 142313939Slinton int sz = tsize(s->stype, s->dimoff, s->sizoff)/SZCHAR; 142413939Slinton 142513939Slinton stabLCSYM = 0; 142613939Slinton if (sz % sizeof (int)) 142713939Slinton sz += sizeof (int) - (sz % sizeof (int)); 142813939Slinton if (s->slevel > 1) 142913939Slinton printf(" .lcomm L%d,%d\n", s->offset, sz); 143013939Slinton else 143113939Slinton printf(" .lcomm %s,%d\n", exname(s->sname), sz); 143224405Smckusick }else if (class == EXTDEF) 143313939Slinton #endif 143424405Smckusick { 143513939Slinton /* simulate initialization by 0 */ 143613939Slinton beginit(p->tn.rval); 143713939Slinton endinit(); 143813939Slinton } 143913939Slinton if( commflag ) commdec( p->tn.rval ); 144013939Slinton } 144113939Slinton 144213939Slinton TWORD 144313939Slinton types( t1, t2, t3 ) TWORD t1, t2, t3; { 144413939Slinton /* return a basic type from basic types t1, t2, and t3 */ 144513939Slinton 144613939Slinton TWORD t[3], noun, adj, unsg; 144713939Slinton register i; 144813939Slinton 144913939Slinton t[0] = t1; 145013939Slinton t[1] = t2; 145113939Slinton t[2] = t3; 145213939Slinton 145313939Slinton unsg = INT; /* INT or UNSIGNED */ 145413939Slinton noun = UNDEF; /* INT, CHAR, or FLOAT */ 145513939Slinton adj = INT; /* INT, LONG, or SHORT */ 145613939Slinton 145713939Slinton for( i=0; i<3; ++i ){ 145813939Slinton switch( t[i] ){ 145913939Slinton 146013939Slinton default: 146113939Slinton bad: 146213939Slinton uerror( "illegal type combination" ); 146313939Slinton return( INT ); 146413939Slinton 146513939Slinton case UNDEF: 146613939Slinton continue; 146713939Slinton 146813939Slinton case UNSIGNED: 146913939Slinton if( unsg != INT ) goto bad; 147013939Slinton unsg = UNSIGNED; 147113939Slinton continue; 147213939Slinton 147313939Slinton case LONG: 147413939Slinton case SHORT: 147513939Slinton if( adj != INT ) goto bad; 147613939Slinton adj = t[i]; 147713939Slinton continue; 147813939Slinton 147913939Slinton case INT: 148013939Slinton case CHAR: 148113939Slinton case FLOAT: 148213939Slinton if( noun != UNDEF ) goto bad; 148313939Slinton noun = t[i]; 148413939Slinton continue; 148513939Slinton } 148613939Slinton } 148713939Slinton 148813939Slinton /* now, construct final type */ 148913939Slinton if( noun == UNDEF ) noun = INT; 149013939Slinton else if( noun == FLOAT ){ 149113939Slinton if( unsg != INT || adj == SHORT ) goto bad; 149213939Slinton return( adj==LONG ? DOUBLE : FLOAT ); 149313939Slinton } 149413939Slinton else if( noun == CHAR && adj != INT ) goto bad; 149513939Slinton 149613939Slinton /* now, noun is INT or CHAR */ 149713939Slinton if( adj != INT ) noun = adj; 149813939Slinton if( unsg == UNSIGNED ) return( noun + (UNSIGNED-INT) ); 149913939Slinton else return( noun ); 150013939Slinton } 150113939Slinton 150213939Slinton NODE * 150313939Slinton tymerge( typ, idp ) NODE *typ, *idp; { 150413939Slinton /* merge type typ with identifier idp */ 150513939Slinton 150613939Slinton register unsigned t; 150713939Slinton register i; 150813939Slinton extern int eprint(); 150913939Slinton 151013939Slinton if( typ->in.op != TYPE ) cerror( "tymerge: arg 1" ); 151113939Slinton if(idp == NIL ) return( NIL ); 151213939Slinton 151313939Slinton # ifndef BUG1 151413939Slinton if( ddebug > 2 ) fwalk( idp, eprint, 0 ); 151513939Slinton # endif 151613939Slinton 151713939Slinton idp->in.type = typ->in.type; 151813939Slinton idp->fn.cdim = curdim; 151913939Slinton tyreduce( idp ); 152013939Slinton idp->fn.csiz = typ->fn.csiz; 152113939Slinton 152213939Slinton for( t=typ->in.type, i=typ->fn.cdim; t&TMASK; t = DECREF(t) ){ 152313939Slinton if( ISARY(t) ) dstash( dimtab[i++] ); 152413939Slinton } 152513939Slinton 152613939Slinton /* now idp is a single node: fix up type */ 152713939Slinton 152813939Slinton idp->in.type = ctype( idp->in.type ); 152913939Slinton 153013939Slinton if( (t = BTYPE(idp->in.type)) != STRTY && t != UNIONTY && t != ENUMTY ){ 153113939Slinton idp->fn.csiz = t; /* in case ctype has rewritten things */ 153213939Slinton } 153313939Slinton 153413939Slinton return( idp ); 153513939Slinton } 153613939Slinton 153713939Slinton tyreduce( p ) register NODE *p; { 153813939Slinton 153913939Slinton /* build a type, and stash away dimensions, from a parse tree of the declaration */ 154013939Slinton /* the type is build top down, the dimensions bottom up */ 154113939Slinton register o, temp; 154213939Slinton register unsigned t; 154313939Slinton 154413939Slinton o = p->in.op; 154513939Slinton p->in.op = FREE; 154613939Slinton 154713939Slinton if( o == NAME ) return; 154813939Slinton 154913939Slinton t = INCREF( p->in.type ); 155013939Slinton if( o == UNARY CALL ) t += (FTN-PTR); 155113939Slinton else if( o == LB ){ 155213939Slinton t += (ARY-PTR); 155313939Slinton temp = p->in.right->tn.lval; 155413939Slinton p->in.right->in.op = FREE; 155532816Sdonn if( temp == 0 && p->in.left->tn.op == LB ) 155632816Sdonn uerror( "null dimension" ); 155713939Slinton } 155813939Slinton 155913939Slinton p->in.left->in.type = t; 156013939Slinton tyreduce( p->in.left ); 156113939Slinton 156213939Slinton if( o == LB ) dstash( temp ); 156313939Slinton 156413939Slinton p->tn.rval = p->in.left->tn.rval; 156513939Slinton p->in.type = p->in.left->in.type; 156613939Slinton 156713939Slinton } 156813939Slinton 156913939Slinton fixtype( p, class ) register NODE *p; { 157013939Slinton register unsigned t, type; 157113939Slinton register mod1, mod2; 157213939Slinton /* fix up the types, and check for legality */ 157313939Slinton 157413939Slinton if( (type = p->in.type) == UNDEF ) return; 157513939Slinton if( mod2 = (type&TMASK) ){ 157613939Slinton t = DECREF(type); 157713939Slinton while( mod1=mod2, mod2 = (t&TMASK) ){ 157813939Slinton if( mod1 == ARY && mod2 == FTN ){ 157913939Slinton uerror( "array of functions is illegal" ); 158013939Slinton type = 0; 158113939Slinton } 158213939Slinton else if( mod1 == FTN && ( mod2 == ARY || mod2 == FTN ) ){ 158313939Slinton uerror( "function returns illegal type" ); 158413939Slinton type = 0; 158513939Slinton } 158613939Slinton t = DECREF(t); 158713939Slinton } 158813939Slinton } 158913939Slinton 159013939Slinton /* detect function arguments, watching out for structure declarations */ 159132816Sdonn /* for example, beware of f(x) struct { int a[10]; } *x; { ... } */ 159213939Slinton /* the danger is that "a" will be converted to a pointer */ 159313939Slinton 159432816Sdonn if( class==SNULL && blevel==1 && !(instruct&(INSTRUCT|INUNION)) ) 159532816Sdonn class = PARAM; 159613939Slinton if( class == PARAM || ( class==REGISTER && blevel==1 ) ){ 159713939Slinton if( type == FLOAT ) type = DOUBLE; 159813939Slinton else if( ISARY(type) ){ 159932816Sdonn #ifdef LINT 160032816Sdonn if( hflag && dimtab[p->fn.cdim]!=0 ) 160132816Sdonn werror("array[%d] type changed to pointer", 160232816Sdonn dimtab[p->fn.cdim]); 160332816Sdonn #endif 160413939Slinton ++p->fn.cdim; 160513939Slinton type += (PTR-ARY); 160613939Slinton } 160713939Slinton else if( ISFTN(type) ){ 160813939Slinton werror( "a function is declared as an argument" ); 160913939Slinton type = INCREF(type); 161013939Slinton } 161113939Slinton 161213939Slinton } 161313939Slinton 161413939Slinton if( instruct && ISFTN(type) ){ 161513939Slinton uerror( "function illegal in structure or union" ); 161613939Slinton type = INCREF(type); 161713939Slinton } 161813939Slinton p->in.type = type; 161913939Slinton } 162013939Slinton 162113939Slinton uclass( class ) register class; { 162213939Slinton /* give undefined version of class */ 162313939Slinton if( class == SNULL ) return( EXTERN ); 162413939Slinton else if( class == STATIC ) return( USTATIC ); 162513939Slinton else if( class == FORTRAN ) return( UFORTRAN ); 162613939Slinton else return( class ); 162713939Slinton } 162813939Slinton 162913939Slinton fixclass( class, type ) TWORD type; { 163013939Slinton 163113939Slinton /* first, fix null class */ 163213939Slinton 163313939Slinton if( class == SNULL ){ 163413939Slinton if( instruct&INSTRUCT ) class = MOS; 163513939Slinton else if( instruct&INUNION ) class = MOU; 163613939Slinton else if( blevel == 0 ) class = EXTDEF; 163713939Slinton else if( blevel == 1 ) class = PARAM; 163813939Slinton else class = AUTO; 163913939Slinton 164013939Slinton } 164113939Slinton 164213939Slinton /* now, do general checking */ 164313939Slinton 164413939Slinton if( ISFTN( type ) ){ 164513939Slinton switch( class ) { 164613939Slinton default: 164713939Slinton uerror( "function has illegal storage class" ); 164813939Slinton case AUTO: 164913939Slinton class = EXTERN; 165013939Slinton case EXTERN: 165113939Slinton case EXTDEF: 165213939Slinton case FORTRAN: 165313939Slinton case TYPEDEF: 165413939Slinton case STATIC: 165513939Slinton case UFORTRAN: 165613939Slinton case USTATIC: 165713939Slinton ; 165813939Slinton } 165913939Slinton } 166013939Slinton 166113939Slinton if( class&FIELD ){ 166213939Slinton if( !(instruct&INSTRUCT) ) uerror( "illegal use of field" ); 166313939Slinton return( class ); 166413939Slinton } 166513939Slinton 166613939Slinton switch( class ){ 166713939Slinton 166813939Slinton case MOU: 166913939Slinton if( !(instruct&INUNION) ) uerror( "illegal class" ); 167013939Slinton return( class ); 167113939Slinton 167213939Slinton case MOS: 167313939Slinton if( !(instruct&INSTRUCT) ) uerror( "illegal class" ); 167413939Slinton return( class ); 167513939Slinton 167613939Slinton case MOE: 167713939Slinton if( instruct & (INSTRUCT|INUNION) ) uerror( "illegal class" ); 167813939Slinton return( class ); 167913939Slinton 168013939Slinton case REGISTER: 168113939Slinton if( blevel == 0 ) uerror( "illegal register declaration" ); 168213939Slinton else if( regvar >= MINRVAR && cisreg( type ) ) return( class ); 168313939Slinton if( blevel == 1 ) return( PARAM ); 168413939Slinton else return( AUTO ); 168513939Slinton 168613939Slinton case AUTO: 168713939Slinton case LABEL: 168813939Slinton case ULABEL: 168913939Slinton if( blevel < 2 ) uerror( "illegal class" ); 169013939Slinton return( class ); 169113939Slinton 169213939Slinton case PARAM: 169313939Slinton if( blevel != 1 ) uerror( "illegal class" ); 169413939Slinton return( class ); 169513939Slinton 169613939Slinton case UFORTRAN: 169713939Slinton case FORTRAN: 169813939Slinton # ifdef NOFORTRAN 169913939Slinton NOFORTRAN; /* a condition which can regulate the FORTRAN usage */ 170013939Slinton # endif 170113939Slinton if( !ISFTN(type) ) uerror( "fortran declaration must apply to function" ); 170213939Slinton else { 170313939Slinton type = DECREF(type); 170413939Slinton if( ISFTN(type) || ISARY(type) || ISPTR(type) ) { 170513939Slinton uerror( "fortran function has wrong type" ); 170613939Slinton } 170713939Slinton } 170813939Slinton case EXTERN: 170913939Slinton case STATIC: 171013939Slinton case EXTDEF: 171113939Slinton case TYPEDEF: 171213939Slinton case USTATIC: 171317151Sralph if( blevel == 1 ){ 171417151Sralph uerror( "illegal class" ); 171517151Sralph return( PARAM ); 171617151Sralph } 171717151Sralph case STNAME: 171817151Sralph case UNAME: 171917151Sralph case ENAME: 172013939Slinton return( class ); 172113939Slinton 172213939Slinton default: 172313939Slinton cerror( "illegal class: %d", class ); 172413939Slinton /* NOTREACHED */ 172513939Slinton 172613939Slinton } 172713939Slinton } 172813939Slinton 172913939Slinton struct symtab * 173013939Slinton mknonuniq(idindex) int *idindex; {/* locate a symbol table entry for */ 173113939Slinton /* an occurrence of a nonunique structure member name */ 173213939Slinton /* or field */ 173313939Slinton register i; 173413939Slinton register struct symtab * sp; 173532817Sdonn char *q; 173613939Slinton 173713939Slinton sp = & stab[ i= *idindex ]; /* position search at old entry */ 173813939Slinton while( sp->stype != TNULL ){ /* locate unused entry */ 173913939Slinton if( ++i >= SYMTSZ ){/* wrap around symbol table */ 174013939Slinton i = 0; 174113939Slinton sp = stab; 174213939Slinton } 174313939Slinton else ++sp; 174413939Slinton if( i == *idindex ) cerror("Symbol table full"); 174513939Slinton } 174613939Slinton sp->sflags = SNONUNIQ | SMOS; 174713939Slinton q = stab[*idindex].sname; /* old entry name */ 174813939Slinton #ifdef FLEXNAMES 174913939Slinton sp->sname = stab[*idindex].sname; 175013939Slinton #endif 175113939Slinton # ifndef BUG1 175213939Slinton if( ddebug ){ 175313939Slinton printf("\tnonunique entry for %s from %d to %d\n", 175413939Slinton q, *idindex, i ); 175513939Slinton } 175613939Slinton # endif 175713939Slinton *idindex = i; 175813939Slinton #ifndef FLEXNAMES 175932817Sdonn { 176032817Sdonn char *p = sp->sname; 176132817Sdonn for( i=1; i<=NCHNAM; ++i ) /* copy name */ 176232817Sdonn if( *p++ = *q /* assign */ ) ++q; 176313939Slinton } 176413939Slinton #endif 176513939Slinton return ( sp ); 176613939Slinton } 176713939Slinton 176813939Slinton lookup( name, s) char *name; { 176913939Slinton /* look up name: must agree with s w.r.t. STAG, SMOS and SHIDDEN */ 177013939Slinton 177113939Slinton register char *p, *q; 177232817Sdonn int i, ii; 177332817Sdonn #ifndef FLEXNAMES 177432817Sdonn int j; 177532817Sdonn #endif 177613939Slinton register struct symtab *sp; 177713939Slinton 177813939Slinton /* compute initial hash index */ 177913939Slinton # ifndef BUG1 178013939Slinton if( ddebug > 2 ){ 178113939Slinton printf( "lookup( %s, %d ), stwart=%d, instruct=%d\n", name, s, stwart, instruct ); 178213939Slinton } 178313939Slinton # endif 178413939Slinton 178513939Slinton i = 0; 178613939Slinton #ifndef FLEXNAMES 178713939Slinton for( p=name, j=0; *p != '\0'; ++p ){ 178813939Slinton i += *p; 178913939Slinton if( ++j >= NCHNAM ) break; 179013939Slinton } 179113939Slinton #else 179213939Slinton i = (int)name; 179313939Slinton #endif 179413939Slinton i = i%SYMTSZ; 179513939Slinton sp = &stab[ii=i]; 179613939Slinton 179713939Slinton for(;;){ /* look for name */ 179813939Slinton 179913939Slinton if( sp->stype == TNULL ){ /* empty slot */ 180013939Slinton sp->sflags = s; /* set STAG, SMOS if needed, turn off all others */ 180113939Slinton #ifndef FLEXNAMES 180213939Slinton p = sp->sname; 180313939Slinton for( j=0; j<NCHNAM; ++j ) if( *p++ = *name ) ++name; 180413939Slinton #else 180513939Slinton sp->sname = name; 180613939Slinton #endif 180713939Slinton sp->stype = UNDEF; 180813939Slinton sp->sclass = SNULL; 180913939Slinton return( i ); 181013939Slinton } 181113939Slinton if( (sp->sflags & (STAG|SMOS|SHIDDEN)) != s ) goto next; 181213939Slinton p = sp->sname; 181313939Slinton q = name; 181413939Slinton #ifndef FLEXNAMES 181513939Slinton for( j=0; j<NCHNAM;++j ){ 181613939Slinton if( *p++ != *q ) goto next; 181713939Slinton if( !*q++ ) break; 181813939Slinton } 181913939Slinton return( i ); 182013939Slinton #else 182113939Slinton if (p == q) 182213939Slinton return ( i ); 182313939Slinton #endif 182413939Slinton next: 182513939Slinton if( ++i >= SYMTSZ ){ 182613939Slinton i = 0; 182713939Slinton sp = stab; 182813939Slinton } 182913939Slinton else ++sp; 183013939Slinton if( i == ii ) cerror( "symbol table full" ); 183113939Slinton } 183213939Slinton } 183313939Slinton 183413939Slinton #ifndef checkst 183513939Slinton /* if not debugging, make checkst a macro */ 183613939Slinton checkst(lev){ 183713939Slinton register int s, i, j; 183813939Slinton register struct symtab *p, *q; 183913939Slinton 184013939Slinton for( i=0, p=stab; i<SYMTSZ; ++i, ++p ){ 184113939Slinton if( p->stype == TNULL ) continue; 184213939Slinton j = lookup( p->sname, p->sflags&(SMOS|STAG) ); 184313939Slinton if( j != i ){ 184413939Slinton q = &stab[j]; 184513939Slinton if( q->stype == UNDEF || 184613939Slinton q->slevel <= p->slevel ){ 184713939Slinton #ifndef FLEXNAMES 184813939Slinton cerror( "check error: %.8s", q->sname ); 184913939Slinton #else 185013939Slinton cerror( "check error: %s", q->sname ); 185113939Slinton #endif 185213939Slinton } 185313939Slinton } 185413939Slinton #ifndef FLEXNAMES 185513939Slinton else if( p->slevel > lev ) cerror( "%.8s check at level %d", p->sname, lev ); 185613939Slinton #else 185713939Slinton else if( p->slevel > lev ) cerror( "%s check at level %d", p->sname, lev ); 185813939Slinton #endif 185913939Slinton } 186013939Slinton } 186113939Slinton #endif 186213939Slinton 186313939Slinton struct symtab * 186413939Slinton relook(p) register struct symtab *p; { /* look up p again, and see where it lies */ 186513939Slinton 186613939Slinton register struct symtab *q; 186713939Slinton 186813939Slinton /* I'm not sure that this handles towers of several hidden definitions in all cases */ 186913939Slinton q = &stab[lookup( p->sname, p->sflags&(STAG|SMOS|SHIDDEN) )]; 187013939Slinton /* make relook always point to either p or an empty cell */ 187113939Slinton if( q->stype == UNDEF ){ 187213939Slinton q->stype = TNULL; 187313939Slinton return(q); 187413939Slinton } 187513939Slinton while( q != p ){ 187613939Slinton if( q->stype == TNULL ) break; 187713939Slinton if( ++q >= &stab[SYMTSZ] ) q=stab; 187813939Slinton } 187913939Slinton return(q); 188013939Slinton } 188113939Slinton 188224405Smckusick clearst( lev ) register int lev; { 188324405Smckusick register struct symtab *p, *q; 188424405Smckusick register int temp; 188524405Smckusick struct symtab *clist = 0; 188613939Slinton 188713939Slinton temp = lineno; 188813939Slinton aobeg(); 188913939Slinton 189024405Smckusick /* step 1: remove entries */ 189124405Smckusick while( chaintop-1 > lev ){ 189224405Smckusick p = schain[--chaintop]; 189324405Smckusick schain[chaintop] = 0; 189424405Smckusick for( ; p; p = q ){ 189524405Smckusick q = p->snext; 189624405Smckusick if( p->stype == TNULL || p->slevel <= lev ) 189724405Smckusick cerror( "schain botch" ); 189824405Smckusick lineno = p->suse < 0 ? -p->suse : p->suse; 189924405Smckusick if( p->stype==UNDEF || ( p->sclass==ULABEL && lev<2 ) ){ 190013939Slinton lineno = temp; 190113939Slinton #ifndef FLEXNAMES 190213939Slinton uerror( "%.8s undefined", p->sname ); 190313939Slinton #else 190413939Slinton uerror( "%s undefined", p->sname ); 190513939Slinton #endif 190613939Slinton } 190713939Slinton else aocode(p); 190813939Slinton # ifndef BUG1 190924405Smckusick if( ddebug ){ 191013939Slinton #ifndef FLEXNAMES 191124405Smckusick printf( "removing %.8s", p->sname ); 191213939Slinton #else 191324405Smckusick printf( "removing %s", p->sname ); 191413939Slinton #endif 191524405Smckusick printf( " from stab[%d], flags %o level %d\n", 191624405Smckusick p-stab, p->sflags, p->slevel); 191724405Smckusick } 191813939Slinton # endif 191924405Smckusick if( p->sflags & SHIDES )unhide( p ); 192013939Slinton p->stype = TNULL; 192124405Smckusick p->snext = clist; 192224405Smckusick clist = p; 192313939Slinton } 192424405Smckusick } 192524405Smckusick 192624405Smckusick /* step 2: fix any mishashed entries */ 192724405Smckusick p = clist; 192824405Smckusick while( p ){ 192932825Sdonn register struct symtab *next, **t, *r; 193024405Smckusick 193124405Smckusick q = p; 193227247Sdonn next = p->snext; 193324405Smckusick for(;;){ 193424405Smckusick if( ++q >= &stab[SYMTSZ] )q = stab; 193524405Smckusick if( q == p || q->stype == TNULL )break; 193624405Smckusick if( (r = relook(q)) != q ) { 193732822Sdonn /* move q in schain list */ 193832825Sdonn t = &schain[q->slevel]; 193932825Sdonn while( *t && *t != q ) 194032825Sdonn t = &(*t)->snext; 194132825Sdonn if( *t ) 194232825Sdonn *t = r; 194332825Sdonn else 194432823Sdonn cerror("schain botch 2"); 194524405Smckusick *r = *q; 194626822Sdonn q->stype = TNULL; 194713939Slinton } 194813939Slinton } 194927247Sdonn p = next; 195013939Slinton } 195124405Smckusick 195213939Slinton lineno = temp; 195313939Slinton aoend(); 195413939Slinton } 195513939Slinton 195613939Slinton hide( p ) register struct symtab *p; { 195713939Slinton register struct symtab *q; 195813939Slinton for( q=p+1; ; ++q ){ 195913939Slinton if( q >= &stab[SYMTSZ] ) q = stab; 196013939Slinton if( q == p ) cerror( "symbol table full" ); 196113939Slinton if( q->stype == TNULL ) break; 196213939Slinton } 196324405Smckusick *q = *p; 196413939Slinton p->sflags |= SHIDDEN; 196513939Slinton q->sflags = (p->sflags&(SMOS|STAG)) | SHIDES; 196613939Slinton #ifndef FLEXNAMES 196713939Slinton if( hflag ) werror( "%.8s redefinition hides earlier one", p->sname ); 196813939Slinton #else 196913939Slinton if( hflag ) werror( "%s redefinition hides earlier one", p->sname ); 197013939Slinton #endif 197113939Slinton # ifndef BUG1 197213939Slinton if( ddebug ) printf( " %d hidden in %d\n", p-stab, q-stab ); 197313939Slinton # endif 197413939Slinton return( idname = q-stab ); 197513939Slinton } 197613939Slinton 197713939Slinton unhide( p ) register struct symtab *p; { 197813939Slinton register struct symtab *q; 197932817Sdonn register s; 198013939Slinton 198113939Slinton s = p->sflags & (SMOS|STAG); 198213939Slinton q = p; 198313939Slinton 198413939Slinton for(;;){ 198513939Slinton 198613939Slinton if( q == stab ) q = &stab[SYMTSZ-1]; 198713939Slinton else --q; 198813939Slinton 198913939Slinton if( q == p ) break; 199013939Slinton 199113939Slinton if( (q->sflags&(SMOS|STAG)) == s ){ 199213939Slinton #ifndef FLEXNAMES 199332817Sdonn register j; 199413939Slinton for( j =0; j<NCHNAM; ++j ) if( p->sname[j] != q->sname[j] ) break; 199513939Slinton if( j == NCHNAM ){ /* found the name */ 199613939Slinton #else 199713939Slinton if (p->sname == q->sname) { 199813939Slinton #endif 199913939Slinton q->sflags &= ~SHIDDEN; 200013939Slinton # ifndef BUG1 200113939Slinton if( ddebug ) printf( "unhide uncovered %d from %d\n", q-stab,p-stab); 200213939Slinton # endif 200313939Slinton return; 200413939Slinton } 200513939Slinton } 200613939Slinton 200713939Slinton } 200813939Slinton cerror( "unhide fails" ); 200913939Slinton } 2010