# include "mfile1" struct instk { int in_sz; /* size of array element */ int in_x; /* current index for structure member in structure initializations */ int in_n; /* number of initializations seen */ int in_s; /* sizoff */ int in_d; /* dimoff */ TWORD in_t; /* type */ int in_id; /* stab index */ int in_fl; /* flag which says if this level is controlled by {} */ OFFSZ in_off; /* offset of the beginning of this level */ } instack[10], *pstk; /* defines used for getting things off of the initialization stack */ struct symtab *relook(); extern ddebug; defid( q, class ) NODE *q; { register struct symtab *p; int idp; TWORD type; TWORD stp; int scl; int dsym, ddef; int slev, temp; if( q == NIL ) return; /* an error was detected */ if( q < node || q >= &node[TREESZ] ) cerror( "defid call" ); idp = q->rval; if( idp < 0 ) cerror( "tyreduce" ); p = &stab[idp]; if( ddebug ){ printf( "defid( %.8s (%d), ", p->sname, idp ); tprint( q->type ); printf( ", %s, (%d,%d) ), level %d\n", scnames(class), q->cdim, q->csiz, blevel ); } fixtype( q, class ); type = q->type; class = fixclass( class, type ); stp = p->stype; slev = p->slevel; if( ddebug ){ printf( " modified to " ); tprint( type ); printf( ", %s\n", scnames(class) ); printf( " previous def'n: " ); tprint( stp ); printf( ", %s, (%d,%d) ), level %d\n", scnames(p->sclass), p->dimoff, p->sizoff, slev ); } if( stp == UNDEF|| stp == FARG ){ if( blevel==1 && stp!=FARG ) switch( class ){ default: if(!(class&FIELD)) uerror( "declared argument %.8s is missing", p->sname ); case MOS: case STNAME: case MOU: case UNAME: case MOE: case ENAME: case TYPEDEF: ; } goto enter; } if( type != stp ) goto mismatch; /* test (and possibly adjust) dimensions */ dsym = p->dimoff; ddef = q->cdim; for( temp=type; temp&TMASK; temp = DECREF(temp) ){ if( ISARY(temp) ){ if( dimtab[dsym] == 0 ) dimtab[dsym] = dimtab[ddef]; else if( dimtab[ddef]!=0 && dimtab[dsym] != dimtab[ddef] ){ goto mismatch; } ++dsym; ++ddef; } } /* check that redeclarations are to the same structure */ if( (temp==STRTY||temp==UNIONTY||temp==ENUMTY) && p->sizoff != q->csiz && (type&TMASK) ) { goto mismatch; } scl = ( p->sclass ); if( ddebug ){ printf( " previous class: %s\n", scnames(scl) ); } if( class&FIELD ){ /* redefinition */ if( !falloc( p, class&FLDSIZ, 1, NIL ) ) { /* successful allocation */ psave( idp ); return; } /* blew it: resume at end of switch... */ } else switch( class ){ case EXTERN: switch( scl ){ case STATIC: case USTATIC: if( slev==0 ) return; break; case EXTDEF: case EXTERN: case FORTRAN: case UFORTRAN: return; } break; case STATIC: if( scl==USTATIC || (scl==EXTERN && blevel==0) ){ p->sclass = STATIC; if( ISFTN(type) ) curftn = idp; return; } break; case USTATIC: if( scl==STATIC || scl==USTATIC ) return; break; case LABEL: if( scl == ULABEL ){ p->sclass = LABEL; deflab( p->offset ); return; } break; case TYPEDEF: if( scl == class ) return; break; case UFORTRAN: if( scl == UFORTRAN || scl == FORTRAN ) return; break; case FORTRAN: if( scl == UFORTRAN ){ p->sclass = FORTRAN; if( ISFTN(type) ) curftn = idp; return; } break; case MOU: case MOS: if( scl == class ) { if( oalloc( p, &strucoff ) ) break; if( class == MOU ) strucoff = 0; psave( idp ); return; } break; case MOE: if( scl == class ){ if( p->offset!= strucoff++ ) break; psave( idp ); } break; case EXTDEF: if( scl == EXTERN ) { p->sclass = EXTDEF; if( ISFTN(type) ) curftn = idp; return; } break; case STNAME: case UNAME: case ENAME: if( scl != class ) break; if( dimtab[p->sizoff] == 0 ) return; /* previous entry just a mention */ break; case ULABEL: if( scl == LABEL || scl == ULABEL ) return; case PARAM: case AUTO: case REGISTER: ; /* mismatch.. */ } mismatch: if( blevel > slev && class != EXTERN && class != FORTRAN && class != UFORTRAN && !( class == LABEL && slev >= 2 ) ){ q->rval = idp = hide( p ); p = &stab[idp]; goto enter; } uerror( "redeclaration of %.8s", p->sname ); if( class==EXTDEF && ISFTN(type) ) curftn = idp; return; enter: /* make a new entry */ if( ddebug ) printf( " new entry made\n" ); p->stype = type; p->sclass = class; p->slevel = blevel; p->offset = NOOFFSET; p->suse = lineno; if( class == STNAME || class == UNAME || class == ENAME ) { p->sizoff = curdim; dstash( 0 ); /* size */ dstash( -1 ); /* index to members of str or union */ dstash( ALSTRUCT ); /* alignment */ } else { switch( BTYPE(type) ){ case STRTY: case UNIONTY: case ENUMTY: p->sizoff = q->csiz; break; default: p->sizoff = BTYPE(type); } } /* copy dimensions */ p->dimoff = q->cdim; /* allocate offsets */ if( class&FIELD ){ falloc( p, class&FLDSIZ, 0, NIL ); /* new entry */ psave( idp ); } else switch( class ){ case AUTO: oalloc( p, &autooff ); break; case STATIC: case EXTDEF: p->offset = getlab(); if( ISFTN(type) ) curftn = idp; break; case ULABEL: case LABEL: p->offset = getlab(); p->slevel = 2; if( class == LABEL ){ locctr( PROG ); deflab( p->offset ); } break; case EXTERN: case UFORTRAN: case FORTRAN: p->offset = getlab(); p->slevel = 0; break; case MOU: case MOS: oalloc( p, &strucoff ); if( class == MOU ) strucoff = 0; psave( idp ); break; case MOE: p->offset = strucoff++; psave( idp ); break; case REGISTER: p->offset = regvar--; if( blevel == 1 ) p->sflags |= SSET; if( regvar < minrvar ) minrvar = regvar; break; } /* user-supplied routine to fix up new definitions */ FIXDEF(p); if( ddebug ) printf( " dimoff, sizoff, offset: %d, %d, %d\n", p->dimoff, p->sizoff, p->offset ); }