117746Sralph #ifndef lint
2*43234Sbostic static char *sccsid ="@(#)pftn.c 1.29 (Berkeley) 06/18/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
defid(q,class)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 break;
22113939Slinton
22213939Slinton case EXTDEF:
22313939Slinton if( scl == EXTERN ) {
22413939Slinton p->sclass = EXTDEF;
22513939Slinton if( ISFTN(type) ) curftn = idp;
22613939Slinton return;
22713939Slinton }
22813939Slinton break;
22913939Slinton
23013939Slinton case STNAME:
23113939Slinton case UNAME:
23213939Slinton case ENAME:
23313939Slinton if( scl != class ) break;
23413939Slinton if( dimtab[p->sizoff] == 0 ) return; /* previous entry just a mention */
23513939Slinton break;
23613939Slinton
23713939Slinton case ULABEL:
23813939Slinton if( scl == LABEL || scl == ULABEL ) return;
23913939Slinton case PARAM:
24013939Slinton case AUTO:
24113939Slinton case REGISTER:
24213939Slinton ; /* mismatch.. */
24313939Slinton
24413939Slinton }
24513939Slinton
24613939Slinton mismatch:
24713939Slinton /* allow nonunique structure/union member names */
24813939Slinton
24913939Slinton if( class==MOU || class==MOS || class & FIELD ){/* make a new entry */
25024405Smckusick register int *memp;
25113939Slinton p->sflags |= SNONUNIQ; /* old entry is nonunique */
25213939Slinton /* determine if name has occurred in this structure/union */
25317981Sralph if (paramno > 0) for( memp = ¶mstk[paramno-1];
25413939Slinton /* while */ *memp>=0 && stab[*memp].sclass != STNAME
25513939Slinton && stab[*memp].sclass != UNAME;
25617981Sralph /* iterate */ --memp){ char *cname, *oname;
25732817Sdonn if( stab[*memp].sflags & SNONUNIQ ){
25813939Slinton cname=p->sname;
25913939Slinton oname=stab[*memp].sname;
26013939Slinton #ifndef FLEXNAMES
26132817Sdonn for(temp=1; temp<=NCHNAM; ++temp){
26213939Slinton if(*cname++ != *oname)goto diff;
26313939Slinton if(!*oname++)break;
26413939Slinton }
26513939Slinton #else
26613939Slinton if (cname != oname) goto diff;
26713939Slinton #endif
26813939Slinton uerror("redeclaration of: %s",p->sname);
26913939Slinton break;
27013939Slinton diff: continue;
27113939Slinton }
27213939Slinton }
27313939Slinton p = mknonuniq( &idp ); /* update p and idp to new entry */
27413939Slinton goto enter;
27513939Slinton }
27613939Slinton if( blevel > slev && class != EXTERN && class != FORTRAN &&
27713939Slinton class != UFORTRAN && !( class == LABEL && slev >= 2 ) ){
27813939Slinton q->tn.rval = idp = hide( p );
27913939Slinton p = &stab[idp];
28013939Slinton goto enter;
28113939Slinton }
28213939Slinton #ifndef FLEXNAMES
28313939Slinton uerror( "redeclaration of %.8s", p->sname );
28413939Slinton #else
28513939Slinton uerror( "redeclaration of %s", p->sname );
28613939Slinton #endif
28713939Slinton if( class==EXTDEF && ISFTN(type) ) curftn = idp;
28813939Slinton return;
28913939Slinton
29013939Slinton enter: /* make a new entry */
29113939Slinton
29213939Slinton # ifndef BUG1
29313939Slinton if( ddebug ) printf( " new entry made\n" );
29413939Slinton # endif
29513939Slinton if( type == UNDEF ) uerror("void type for %s",p->sname);
29613939Slinton p->stype = type;
29713939Slinton p->sclass = class;
29813939Slinton p->slevel = blevel;
29913939Slinton p->offset = NOOFFSET;
30013939Slinton p->suse = lineno;
30113939Slinton if( class == STNAME || class == UNAME || class == ENAME ) {
30213939Slinton p->sizoff = curdim;
30313939Slinton dstash( 0 ); /* size */
30413939Slinton dstash( -1 ); /* index to members of str or union */
30513939Slinton dstash( ALSTRUCT ); /* alignment */
30613939Slinton dstash( idp );
30713939Slinton }
30813939Slinton else {
30913939Slinton switch( BTYPE(type) ){
31013939Slinton case STRTY:
31113939Slinton case UNIONTY:
31213939Slinton case ENUMTY:
31313939Slinton p->sizoff = q->fn.csiz;
31413939Slinton break;
31513939Slinton default:
31613939Slinton p->sizoff = BTYPE(type);
31713939Slinton }
31813939Slinton }
31913939Slinton
32013939Slinton /* copy dimensions */
32113939Slinton
32213939Slinton p->dimoff = q->fn.cdim;
32313939Slinton
32413939Slinton /* allocate offsets */
32513939Slinton if( class&FIELD ){
32632817Sdonn (void) falloc( p, class&FLDSIZ, 0, NIL ); /* new entry */
32713939Slinton psave( idp );
32813939Slinton }
32913939Slinton else switch( class ){
33013939Slinton
33113939Slinton case AUTO:
33232817Sdonn (void) oalloc( p, &autooff );
33313939Slinton break;
33413939Slinton case STATIC:
33513939Slinton case EXTDEF:
33613939Slinton p->offset = getlab();
33713939Slinton if( ISFTN(type) ) curftn = idp;
33813939Slinton break;
33913939Slinton case ULABEL:
34013939Slinton case LABEL:
34113939Slinton p->offset = getlab();
34213939Slinton p->slevel = 2;
34313939Slinton if( class == LABEL ){
34432817Sdonn (void) locctr( PROG );
34513939Slinton deflab( p->offset );
34613939Slinton }
34713939Slinton break;
34813939Slinton
34913939Slinton case EXTERN:
35013939Slinton case UFORTRAN:
35113939Slinton case FORTRAN:
35213939Slinton p->offset = getlab();
35313939Slinton p->slevel = 0;
35413939Slinton break;
35513939Slinton case MOU:
35613939Slinton case MOS:
35732817Sdonn (void) oalloc( p, &strucoff );
35813939Slinton if( class == MOU ) strucoff = 0;
35913939Slinton psave( idp );
36013939Slinton break;
36113939Slinton
36213939Slinton case MOE:
36313939Slinton p->offset = strucoff++;
36413939Slinton psave( idp );
36513939Slinton break;
36613939Slinton case REGISTER:
36713939Slinton p->offset = regvar--;
36813939Slinton if( blevel == 1 ) p->sflags |= SSET;
36913939Slinton if( regvar < minrvar ) minrvar = regvar;
37013939Slinton break;
37113939Slinton }
37213939Slinton
37324405Smckusick {
37424405Smckusick register int l = p->slevel;
37524405Smckusick
37624405Smckusick if( l >= MAXSCOPES )
37724405Smckusick cerror( "scopes nested too deep" );
37824405Smckusick
37924405Smckusick p->snext = schain[l];
38024405Smckusick schain[l] = p;
38124405Smckusick if( l >= chaintop )
38224405Smckusick chaintop = l + 1;
38324405Smckusick }
38424405Smckusick
38513939Slinton /* user-supplied routine to fix up new definitions */
38613939Slinton
38713939Slinton FIXDEF(p);
38813939Slinton
38913939Slinton # ifndef BUG1
39013939Slinton if( ddebug ) printf( " dimoff, sizoff, offset: %d, %d, %d\n", p->dimoff, p->sizoff, p->offset );
39113939Slinton # endif
39213939Slinton
39313939Slinton }
39413939Slinton
psave(i)39513939Slinton psave( i ){
39613939Slinton if( paramno >= PARAMSZ ){
39713939Slinton cerror( "parameter stack overflow");
39813939Slinton }
39913939Slinton paramstk[ paramno++ ] = i;
40013939Slinton }
40113939Slinton
ftnend()40213939Slinton ftnend(){ /* end of function */
40332814Sdonn if( retlab != NOLAB && nerrors == 0 ){ /* inside a real function */
40413939Slinton efcode();
40513939Slinton }
40613939Slinton checkst(0);
40713939Slinton retstat = 0;
40813939Slinton tcheck();
40913939Slinton curclass = SNULL;
41013939Slinton brklab = contlab = retlab = NOLAB;
41113939Slinton flostat = 0;
41213939Slinton if( nerrors == 0 ){
41313939Slinton if( psavbc != & asavbc[0] ) cerror("bcsave error");
41413939Slinton if( paramno != 0 ) cerror("parameter reset error");
41513939Slinton if( swx != 0 ) cerror( "switch error");
41613939Slinton }
41713939Slinton psavbc = &asavbc[0];
41813939Slinton paramno = 0;
41913939Slinton autooff = AUTOINIT;
42013939Slinton minrvar = regvar = MAXRVAR;
42113939Slinton reached = 1;
42213939Slinton swx = 0;
42313939Slinton swp = swtab;
42432817Sdonn (void) locctr(DATA);
42513939Slinton }
42613939Slinton
dclargs()42713939Slinton dclargs(){
42813939Slinton register i, j;
42913939Slinton register struct symtab *p;
43013939Slinton register NODE *q;
43113939Slinton argoff = ARGINIT;
43213939Slinton # ifndef BUG1
43313939Slinton if( ddebug > 2) printf("dclargs()\n");
43413939Slinton # endif
43513939Slinton for( i=0; i<paramno; ++i ){
43613939Slinton if( (j = paramstk[i]) < 0 ) continue;
43713939Slinton p = &stab[j];
43813939Slinton # ifndef BUG1
43913939Slinton if( ddebug > 2 ){
44013939Slinton printf("\t%s (%d) ",p->sname, j);
44113939Slinton tprint(p->stype);
44213939Slinton printf("\n");
44313939Slinton }
44413939Slinton # endif
44513939Slinton if( p->stype == FARG ) {
44613939Slinton q = block(FREE,NIL,NIL,INT,0,INT);
44713939Slinton q->tn.rval = j;
44813939Slinton defid( q, PARAM );
44913939Slinton }
45013939Slinton FIXARG(p); /* local arg hook, eg. for sym. debugger */
45113939Slinton oalloc( p, &argoff ); /* always set aside space, even for register arguments */
45213939Slinton }
45313939Slinton cendarg();
45432817Sdonn (void) locctr(PROG);
45513939Slinton defalign(ALINT);
45613939Slinton ftnno = getlab();
45713939Slinton bfcode( paramstk, paramno );
45813939Slinton paramno = 0;
45913939Slinton }
46013939Slinton
46113939Slinton NODE *
rstruct(idn,soru)46213939Slinton rstruct( idn, soru ){ /* reference to a structure or union, with no definition */
46313939Slinton register struct symtab *p;
46413939Slinton register NODE *q;
46513939Slinton p = &stab[idn];
46613939Slinton switch( p->stype ){
46713939Slinton
46813939Slinton case UNDEF:
46913939Slinton def:
47013939Slinton q = block( FREE, NIL, NIL, 0, 0, 0 );
47113939Slinton q->tn.rval = idn;
47213939Slinton q->in.type = (soru&INSTRUCT) ? STRTY : ( (soru&INUNION) ? UNIONTY : ENUMTY );
47313939Slinton defid( q, (soru&INSTRUCT) ? STNAME : ( (soru&INUNION) ? UNAME : ENAME ) );
47413939Slinton break;
47513939Slinton
47613939Slinton case STRTY:
47713939Slinton if( soru & INSTRUCT ) break;
47813939Slinton goto def;
47913939Slinton
48013939Slinton case UNIONTY:
48113939Slinton if( soru & INUNION ) break;
48213939Slinton goto def;
48313939Slinton
48413939Slinton case ENUMTY:
48513939Slinton if( !(soru&(INUNION|INSTRUCT)) ) break;
48613939Slinton goto def;
48713939Slinton
48813939Slinton }
48913939Slinton stwart = instruct;
49013939Slinton return( mkty( p->stype, 0, p->sizoff ) );
49113939Slinton }
49213939Slinton
moedef(idn)49313939Slinton moedef( idn ){
49413939Slinton register NODE *q;
49513939Slinton
49613939Slinton q = block( FREE, NIL, NIL, MOETY, 0, 0 );
49713939Slinton q->tn.rval = idn;
49813939Slinton if( idn>=0 ) defid( q, MOE );
49913939Slinton }
50013939Slinton
bstruct(idn,soru)50113939Slinton bstruct( idn, soru ){ /* begining of structure or union declaration */
50213939Slinton register NODE *q;
50313939Slinton
50413939Slinton psave( instruct );
50513939Slinton psave( curclass );
50613939Slinton psave( strucoff );
50713939Slinton strucoff = 0;
50813939Slinton instruct = soru;
50913939Slinton q = block( FREE, NIL, NIL, 0, 0, 0 );
51013939Slinton q->tn.rval = idn;
51113939Slinton if( instruct==INSTRUCT ){
51213939Slinton curclass = MOS;
51313939Slinton q->in.type = STRTY;
51413939Slinton if( idn >= 0 ) defid( q, STNAME );
51513939Slinton }
51613939Slinton else if( instruct == INUNION ) {
51713939Slinton curclass = MOU;
51813939Slinton q->in.type = UNIONTY;
51913939Slinton if( idn >= 0 ) defid( q, UNAME );
52013939Slinton }
52113939Slinton else { /* enum */
52213939Slinton curclass = MOE;
52313939Slinton q->in.type = ENUMTY;
52413939Slinton if( idn >= 0 ) defid( q, ENAME );
52513939Slinton }
52613939Slinton psave( idn = q->tn.rval );
52713939Slinton /* the "real" definition is where the members are seen */
52813939Slinton if ( idn >= 0 ) stab[idn].suse = lineno;
52913939Slinton return( paramno-4 );
53013939Slinton }
53113939Slinton
53213939Slinton NODE *
dclstruct(oparam)53313939Slinton dclstruct( oparam ){
53413939Slinton register struct symtab *p;
53513939Slinton register i, al, sa, j, sz, szindex;
53613939Slinton register TWORD temp;
53713939Slinton register high, low;
53813939Slinton
53932817Sdonn /* paramstk contains:
54032817Sdonn paramstk[ oparam ] = previous instruct
54132817Sdonn paramstk[ oparam+1 ] = previous class
54213939Slinton paramstk[ oparam+2 ] = previous strucoff
54313939Slinton paramstk[ oparam+3 ] = structure name
54413939Slinton
54513939Slinton paramstk[ oparam+4, ... ] = member stab indices
54613939Slinton
54713939Slinton */
54813939Slinton
54913939Slinton
55013939Slinton if( (i=paramstk[oparam+3]) < 0 ){
55113939Slinton szindex = curdim;
55213939Slinton dstash( 0 ); /* size */
55313939Slinton dstash( -1 ); /* index to member names */
55413939Slinton dstash( ALSTRUCT ); /* alignment */
55513939Slinton dstash( -lineno ); /* name of structure */
55613939Slinton }
55713939Slinton else {
55813939Slinton szindex = stab[i].sizoff;
55913939Slinton }
56013939Slinton
56113939Slinton # ifndef BUG1
56213939Slinton if( ddebug ){
56313939Slinton #ifndef FLEXNAMES
56413939Slinton printf( "dclstruct( %.8s ), szindex = %d\n", (i>=0)? stab[i].sname : "??", szindex );
56513939Slinton #else
56613939Slinton printf( "dclstruct( %s ), szindex = %d\n", (i>=0)? stab[i].sname : "??", szindex );
56713939Slinton #endif
56813939Slinton }
56913939Slinton # endif
57013939Slinton temp = (instruct&INSTRUCT)?STRTY:((instruct&INUNION)?UNIONTY:ENUMTY);
57113939Slinton stwart = instruct = paramstk[ oparam ];
57213939Slinton curclass = paramstk[ oparam+1 ];
57313939Slinton dimtab[ szindex+1 ] = curdim;
57413939Slinton al = ALSTRUCT;
57513939Slinton
57613939Slinton high = low = 0;
57713939Slinton
57813939Slinton for( i = oparam+4; i< paramno; ++i ){
57913939Slinton dstash( j=paramstk[i] );
58013939Slinton if( j<0 || j>= SYMTSZ ) cerror( "gummy structure member" );
58113939Slinton p = &stab[j];
58213939Slinton if( temp == ENUMTY ){
58313939Slinton if( p->offset < low ) low = p->offset;
58413939Slinton if( p->offset > high ) high = p->offset;
58513939Slinton p->sizoff = szindex;
58613939Slinton continue;
58713939Slinton }
58813939Slinton sa = talign( p->stype, p->sizoff );
58913939Slinton if( p->sclass & FIELD ){
59013939Slinton sz = p->sclass&FLDSIZ;
59113939Slinton }
59213939Slinton else {
59313939Slinton sz = tsize( p->stype, p->dimoff, p->sizoff );
59413939Slinton }
59513939Slinton if( sz == 0 ){
59613939Slinton #ifndef FLEXNAMES
59713939Slinton werror( "illegal zero sized structure member: %.8s", p->sname );
59813939Slinton #else
59913939Slinton werror( "illegal zero sized structure member: %s", p->sname );
60013939Slinton #endif
60113939Slinton }
60213939Slinton if( sz > strucoff ) strucoff = sz; /* for use with unions */
60313939Slinton SETOFF( al, sa );
60413939Slinton /* set al, the alignment, to the lcm of the alignments of the members */
60513939Slinton }
60613939Slinton dstash( -1 ); /* endmarker */
60713939Slinton SETOFF( strucoff, al );
60813939Slinton
60913939Slinton if( temp == ENUMTY ){
61013939Slinton register TWORD ty;
61113939Slinton
61213939Slinton # ifdef ENUMSIZE
61313939Slinton ty = ENUMSIZE(high,low);
61413939Slinton # else
61513939Slinton if( (char)high == high && (char)low == low ) ty = ctype( CHAR );
61613939Slinton else if( (short)high == high && (short)low == low ) ty = ctype( SHORT );
61713939Slinton else ty = ctype(INT);
61813939Slinton #endif
61913939Slinton strucoff = tsize( ty, 0, (int)ty );
62013939Slinton dimtab[ szindex+2 ] = al = talign( ty, (int)ty );
62113939Slinton }
62213939Slinton
62313939Slinton if( strucoff == 0 ) uerror( "zero sized structure" );
62413939Slinton dimtab[ szindex ] = strucoff;
62513939Slinton dimtab[ szindex+2 ] = al;
62613939Slinton dimtab[ szindex+3 ] = paramstk[ oparam+3 ]; /* name index */
62713939Slinton
62813939Slinton FIXSTRUCT( szindex, oparam ); /* local hook, eg. for sym debugger */
62913939Slinton # ifndef BUG1
63013939Slinton if( ddebug>1 ){
63113939Slinton printf( "\tdimtab[%d,%d,%d] = %d,%d,%d\n", szindex,szindex+1,szindex+2,
63213939Slinton dimtab[szindex],dimtab[szindex+1],dimtab[szindex+2] );
63313939Slinton for( i = dimtab[szindex+1]; dimtab[i] >= 0; ++i ){
63413939Slinton #ifndef FLEXNAMES
63513939Slinton printf( "\tmember %.8s(%d)\n", stab[dimtab[i]].sname, dimtab[i] );
63613939Slinton #else
63713939Slinton printf( "\tmember %s(%d)\n", stab[dimtab[i]].sname, dimtab[i] );
63813939Slinton #endif
63913939Slinton }
64013939Slinton }
64113939Slinton # endif
64213939Slinton
64313939Slinton strucoff = paramstk[ oparam+2 ];
64413939Slinton paramno = oparam;
64513939Slinton
64613939Slinton return( mkty( temp, 0, szindex ) );
64713939Slinton }
64813939Slinton
64913939Slinton /* VARARGS */
yyerror(s)65013939Slinton yyerror( s ) char *s; { /* error printing routine in parser */
65113939Slinton
65213939Slinton uerror( s );
65313939Slinton
65413939Slinton }
65513939Slinton
yyaccpt()65613939Slinton yyaccpt(){
65713939Slinton ftnend();
65813939Slinton }
65913939Slinton
ftnarg(idn)66013939Slinton ftnarg( idn ) {
66113939Slinton switch( stab[idn].stype ){
66213939Slinton
66313939Slinton case UNDEF:
66413939Slinton /* this parameter, entered at scan */
66513939Slinton break;
66613939Slinton case FARG:
66713939Slinton #ifndef FLEXNAMES
66813939Slinton uerror("redeclaration of formal parameter, %.8s",
66913939Slinton #else
67013939Slinton uerror("redeclaration of formal parameter, %s",
67113939Slinton #endif
67213939Slinton stab[idn].sname);
67313939Slinton /* fall thru */
67413939Slinton case FTN:
67513939Slinton /* the name of this function matches parm */
67613939Slinton /* fall thru */
67713939Slinton default:
67813939Slinton idn = hide( &stab[idn]);
67913939Slinton break;
68013939Slinton case TNULL:
68113939Slinton /* unused entry, fill it */
68213939Slinton ;
68313939Slinton }
68413939Slinton stab[idn].stype = FARG;
68513939Slinton stab[idn].sclass = PARAM;
68613939Slinton psave( idn );
68713939Slinton }
68813939Slinton
talign(ty,s)68913939Slinton talign( ty, s) register unsigned ty; register s; {
69013939Slinton /* compute the alignment of an object with type ty, sizeoff index s */
69113939Slinton
69213939Slinton register i;
69313939Slinton if( s<0 && ty!=INT && ty!=CHAR && ty!=SHORT && ty!=UNSIGNED && ty!=UCHAR && ty!=USHORT
69413939Slinton #ifdef LONGFIELDS
69513939Slinton && ty!=LONG && ty!=ULONG
69613939Slinton #endif
69713939Slinton ){
69813939Slinton return( fldal( ty ) );
69913939Slinton }
70013939Slinton
70113939Slinton for( i=0; i<=(SZINT-BTSHIFT-1); i+=TSHIFT ){
70213939Slinton switch( (ty>>i)&TMASK ){
70313939Slinton
70413939Slinton case FTN:
70541145Smckusick uerror( "can't assign to function" );
70641145Smckusick return( ALCHAR );
70713939Slinton case PTR:
70813939Slinton return( ALPOINT );
70913939Slinton case ARY:
71013939Slinton continue;
71113939Slinton case 0:
71213939Slinton break;
71313939Slinton }
71413939Slinton }
71513939Slinton
71613939Slinton switch( BTYPE(ty) ){
71713939Slinton
71813939Slinton case UNIONTY:
71913939Slinton case ENUMTY:
72013939Slinton case STRTY:
72113939Slinton return( (unsigned int) dimtab[ s+2 ] );
72213939Slinton case CHAR:
72313939Slinton case UCHAR:
72413939Slinton return( ALCHAR );
72513939Slinton case FLOAT:
72613939Slinton return( ALFLOAT );
72713939Slinton case DOUBLE:
72813939Slinton return( ALDOUBLE );
72913939Slinton case LONG:
73013939Slinton case ULONG:
73113939Slinton return( ALLONG );
73213939Slinton case SHORT:
73313939Slinton case USHORT:
73413939Slinton return( ALSHORT );
73513939Slinton default:
73613939Slinton return( ALINT );
73713939Slinton }
73813939Slinton }
73913939Slinton
74013939Slinton OFFSZ
tsize(ty,d,s)74113939Slinton tsize( ty, d, s ) TWORD ty; {
74213939Slinton /* compute the size associated with type ty,
74313939Slinton dimoff d, and sizoff s */
74413939Slinton /* BETTER NOT BE CALLED WHEN t, d, and s REFER TO A BIT FIELD... */
74513939Slinton
74613939Slinton int i;
74713939Slinton OFFSZ mult;
74813939Slinton
74913939Slinton mult = 1;
75013939Slinton
75113939Slinton for( i=0; i<=(SZINT-BTSHIFT-1); i+=TSHIFT ){
75213939Slinton switch( (ty>>i)&TMASK ){
75313939Slinton
75413939Slinton case FTN:
75532819Sdonn /* cerror( "compiler takes size of function"); */
75632819Sdonn uerror( "can't take size of function" );
75732819Sdonn return( SZCHAR );
75813939Slinton case PTR:
75913939Slinton return( SZPOINT * mult );
76013939Slinton case ARY:
76113939Slinton mult *= (unsigned int) dimtab[ d++ ];
76213939Slinton continue;
76313939Slinton case 0:
76413939Slinton break;
76513939Slinton
76613939Slinton }
76713939Slinton }
76813939Slinton
76913939Slinton if( dimtab[s]==0 ) {
77025749Sdonn if( ty == STRTY )
77125749Sdonn uerror( "undefined structure" );
77225749Sdonn else
77325749Sdonn uerror( "unknown size");
77413939Slinton return( SZINT );
77513939Slinton }
77613939Slinton return( (unsigned int) dimtab[ s ] * mult );
77713939Slinton }
77813939Slinton
inforce(n)77913939Slinton inforce( n ) OFFSZ n; { /* force inoff to have the value n */
78013939Slinton /* inoff is updated to have the value n */
78113939Slinton OFFSZ wb;
78213939Slinton register rest;
78313939Slinton /* rest is used to do a lot of conversion to ints... */
78413939Slinton
78513939Slinton if( inoff == n ) return;
78613939Slinton if( inoff > n ) {
78713939Slinton cerror( "initialization alignment error");
78813939Slinton }
78913939Slinton
79013939Slinton wb = inoff;
79113939Slinton SETOFF( wb, SZINT );
79213939Slinton
79313939Slinton /* wb now has the next higher word boundary */
79413939Slinton
79513939Slinton if( wb >= n ){ /* in the same word */
79613939Slinton rest = n - inoff;
79713939Slinton vfdzero( rest );
79813939Slinton return;
79913939Slinton }
80013939Slinton
80113939Slinton /* otherwise, extend inoff to be word aligned */
80213939Slinton
80313939Slinton rest = wb - inoff;
80413939Slinton vfdzero( rest );
80513939Slinton
80613939Slinton /* now, skip full words until near to n */
80713939Slinton
80813939Slinton rest = (n-inoff)/SZINT;
80913939Slinton zecode( rest );
81013939Slinton
81113939Slinton /* now, the remainder of the last word */
81213939Slinton
81313939Slinton rest = n-inoff;
81413939Slinton vfdzero( rest );
81513939Slinton if( inoff != n ) cerror( "inoff error");
81613939Slinton
81713939Slinton }
81813939Slinton
vfdalign(n)81913939Slinton vfdalign( n ){ /* make inoff have the offset the next alignment of n */
82013939Slinton OFFSZ m;
82113939Slinton
82213939Slinton m = inoff;
82313939Slinton SETOFF( m, n );
82413939Slinton inforce( m );
82513939Slinton }
82613939Slinton
82713939Slinton
82813939Slinton int idebug = 0;
82913939Slinton
83013939Slinton int ibseen = 0; /* the number of } constructions which have been filled */
83113939Slinton
83227247Sdonn int ifull = 0; /* 1 if all initializers have been seen */
83327247Sdonn
83413939Slinton int iclass; /* storage class of thing being initialized */
83513939Slinton
83613939Slinton int ilocctr = 0; /* location counter for current initialization */
83713939Slinton
beginit(curid)83813939Slinton beginit(curid){
83913939Slinton /* beginning of initilization; set location ctr and set type */
84013939Slinton register struct symtab *p;
84113939Slinton
84213939Slinton # ifndef BUG1
84313939Slinton if( idebug >= 3 ) printf( "beginit(), curid = %d\n", curid );
84413939Slinton # endif
84513939Slinton
84613939Slinton p = &stab[curid];
84713939Slinton
84813939Slinton iclass = p->sclass;
84913939Slinton if( curclass == EXTERN || curclass == FORTRAN ) iclass = EXTERN;
85013939Slinton switch( iclass ){
85113939Slinton
85213939Slinton case UNAME:
85313939Slinton case EXTERN:
85413939Slinton return;
85513939Slinton case AUTO:
85613939Slinton case REGISTER:
85713939Slinton break;
85813939Slinton case EXTDEF:
85913939Slinton case STATIC:
86013939Slinton ilocctr = ISARY(p->stype)?ADATA:DATA;
86132814Sdonn if( nerrors == 0 ){
86232817Sdonn (void) locctr( ilocctr );
86332814Sdonn defalign( talign( p->stype, p->sizoff ) );
86432814Sdonn defnam( p );
86532814Sdonn }
86613939Slinton
86713939Slinton }
86813939Slinton
86913939Slinton inoff = 0;
87013939Slinton ibseen = 0;
87127247Sdonn ifull = 0;
87213939Slinton
87313939Slinton pstk = 0;
87413939Slinton
87513939Slinton instk( curid, p->stype, p->dimoff, p->sizoff, inoff );
87613939Slinton
87713939Slinton }
87813939Slinton
instk(id,t,d,s,off)87913939Slinton instk( id, t, d, s, off ) OFFSZ off; TWORD t; {
88013939Slinton /* make a new entry on the parameter stack to initialize id */
88113939Slinton
88213939Slinton register struct symtab *p;
88313939Slinton
88413939Slinton for(;;){
88513939Slinton # ifndef BUG1
88613939Slinton if( idebug ) printf( "instk((%d, %o,%d,%d, %d)\n", id, t, d, s, off );
88713939Slinton # endif
88813939Slinton
88913939Slinton /* save information on the stack */
89013939Slinton
89113939Slinton if( !pstk ) pstk = instack;
89213939Slinton else ++pstk;
89313939Slinton
89413939Slinton pstk->in_fl = 0; /* { flag */
89513939Slinton pstk->in_id = id ;
89613939Slinton pstk->in_t = t ;
89713939Slinton pstk->in_d = d ;
89813939Slinton pstk->in_s = s ;
89913939Slinton pstk->in_n = 0; /* number seen */
90013939Slinton pstk->in_x = t==STRTY ?dimtab[s+1] : 0 ;
90113939Slinton pstk->in_off = off; /* offset at the beginning of this element */
90213939Slinton /* if t is an array, DECREF(t) can't be a field */
90313939Slinton /* INS_sz has size of array elements, and -size for fields */
90413939Slinton if( ISARY(t) ){
90513939Slinton pstk->in_sz = tsize( DECREF(t), d+1, s );
90613939Slinton }
90713939Slinton else if( stab[id].sclass & FIELD ){
90813939Slinton pstk->in_sz = - ( stab[id].sclass & FLDSIZ );
90913939Slinton }
91013939Slinton else {
91113939Slinton pstk->in_sz = 0;
91213939Slinton }
91313939Slinton
91413939Slinton if( (iclass==AUTO || iclass == REGISTER ) &&
91513939Slinton (ISARY(t) || t==STRTY) ) uerror( "no automatic aggregate initialization" );
91613939Slinton
91713939Slinton /* now, if this is not a scalar, put on another element */
91813939Slinton
91913939Slinton if( ISARY(t) ){
92013939Slinton t = DECREF(t);
92113939Slinton ++d;
92213939Slinton continue;
92313939Slinton }
92413939Slinton else if( t == STRTY ){
92525749Sdonn if( dimtab[pstk->in_s] == 0 ){
92625749Sdonn uerror( "can't initialize undefined structure" );
92725749Sdonn iclass = -1;
92825749Sdonn return;
92925749Sdonn }
93013939Slinton id = dimtab[pstk->in_x];
93113939Slinton p = &stab[id];
93213939Slinton if( p->sclass != MOS && !(p->sclass&FIELD) ) cerror( "insane structure member list" );
93313939Slinton t = p->stype;
93413939Slinton d = p->dimoff;
93513939Slinton s = p->sizoff;
93613939Slinton off += p->offset;
93713939Slinton continue;
93813939Slinton }
93913939Slinton else return;
94013939Slinton }
94113939Slinton }
94213939Slinton
94313939Slinton NODE *
getstr()94413939Slinton getstr(){ /* decide if the string is external or an initializer, and get the contents accordingly */
94513939Slinton
94613939Slinton register l, temp;
94713939Slinton register NODE *p;
94813939Slinton
94913939Slinton if( (iclass==EXTDEF||iclass==STATIC) && (pstk->in_t == CHAR || pstk->in_t == UCHAR) &&
95013939Slinton pstk!=instack && ISARY( pstk[-1].in_t ) ){
95113939Slinton /* treat "abc" as { 'a', 'b', 'c', 0 } */
95213939Slinton strflg = 1;
95313939Slinton ilbrace(); /* simulate { */
95413939Slinton inforce( pstk->in_off );
95513939Slinton /* if the array is inflexible (not top level), pass in the size and
95613939Slinton be prepared to throw away unwanted initializers */
95713939Slinton lxstr((pstk-1)!=instack?dimtab[(pstk-1)->in_d]:0); /* get the contents */
95813939Slinton irbrace(); /* simulate } */
95913939Slinton return( NIL );
96013939Slinton }
96113939Slinton else { /* make a label, and get the contents and stash them away */
96213939Slinton if( iclass != SNULL ){ /* initializing */
96313939Slinton /* fill out previous word, to permit pointer */
96413939Slinton vfdalign( ALPOINT );
96513939Slinton }
96613939Slinton temp = locctr( blevel==0?ISTRNG:STRNG ); /* set up location counter */
96713939Slinton deflab( l = getlab() );
96813939Slinton strflg = 0;
96913939Slinton lxstr(0); /* get the contents */
97032817Sdonn (void) locctr( blevel==0?ilocctr:temp );
97113939Slinton p = buildtree( STRING, NIL, NIL );
97213939Slinton p->tn.rval = -l;
97313939Slinton return(p);
97413939Slinton }
97513939Slinton }
97613939Slinton
putbyte(v)97713939Slinton putbyte( v ){ /* simulate byte v appearing in a list of integer values */
97813939Slinton register NODE *p;
97913939Slinton p = bcon(v);
98013939Slinton incode( p, SZCHAR );
98113939Slinton tfree( p );
98213939Slinton gotscal();
98313939Slinton }
98413939Slinton
endinit()98513939Slinton endinit(){
98613939Slinton register TWORD t;
98713939Slinton register d, s, n, d1;
98813939Slinton
98913939Slinton # ifndef BUG1
99013939Slinton if( idebug ) printf( "endinit(), inoff = %d\n", inoff );
99113939Slinton # endif
99213939Slinton
99313939Slinton switch( iclass ){
99413939Slinton
99513939Slinton case EXTERN:
99613939Slinton case AUTO:
99713939Slinton case REGISTER:
99825749Sdonn case -1:
99913939Slinton return;
100013939Slinton }
100113939Slinton
100213939Slinton pstk = instack;
100313939Slinton
100413939Slinton t = pstk->in_t;
100513939Slinton d = pstk->in_d;
100613939Slinton s = pstk->in_s;
100713939Slinton n = pstk->in_n;
100813939Slinton
100913939Slinton if( ISARY(t) ){
101013939Slinton d1 = dimtab[d];
101113939Slinton
101213939Slinton vfdalign( pstk->in_sz ); /* fill out part of the last element, if needed */
101313939Slinton n = inoff/pstk->in_sz; /* real number of initializers */
101413939Slinton if( d1 >= n ){
101513939Slinton /* once again, t is an array, so no fields */
101613939Slinton inforce( tsize( t, d, s ) );
101713939Slinton n = d1;
101813939Slinton }
101913939Slinton if( d1!=0 && d1!=n ) uerror( "too many initializers");
102013939Slinton if( n==0 ) werror( "empty array declaration");
102113939Slinton dimtab[d] = n;
102213942Slinton if( d1==0 ) FIXDEF(&stab[pstk->in_id]);
102313939Slinton }
102413939Slinton
102513939Slinton else if( t == STRTY || t == UNIONTY ){
102613939Slinton /* clearly not fields either */
102713939Slinton inforce( tsize( t, d, s ) );
102813939Slinton }
102913939Slinton else if( n > 1 ) uerror( "bad scalar initialization");
103013939Slinton /* this will never be called with a field element... */
103113939Slinton else inforce( tsize(t,d,s) );
103213939Slinton
103313939Slinton paramno = 0;
103413939Slinton vfdalign( AL_INIT );
103513939Slinton inoff = 0;
103613939Slinton iclass = SNULL;
103713939Slinton
103813939Slinton }
103913939Slinton
fixinit()104032818Sdonn fixinit(){
104132818Sdonn /* called from the grammar if we must punt during initialization */
104232818Sdonn /* stolen from endinit() */
104332818Sdonn pstk = instack;
104432818Sdonn paramno = 0;
104532818Sdonn vfdalign( AL_INIT );
104632818Sdonn inoff = 0;
104732818Sdonn iclass = SNULL;
104832818Sdonn }
104932818Sdonn
doinit(p)105013939Slinton doinit( p ) register NODE *p; {
105113939Slinton
105213939Slinton /* take care of generating a value for the initializer p */
105313939Slinton /* inoff has the current offset (last bit written)
105413939Slinton in the current word being generated */
105513939Slinton
105613939Slinton register sz, d, s;
105713939Slinton register TWORD t;
105817746Sralph int o;
105913939Slinton
106013939Slinton /* note: size of an individual initializer is assumed to fit into an int */
106113939Slinton
106232814Sdonn if( iclass < 0 ) goto leave;
106313939Slinton if( iclass == EXTERN || iclass == UNAME ){
106413939Slinton uerror( "cannot initialize extern or union" );
106513939Slinton iclass = -1;
106613939Slinton goto leave;
106713939Slinton }
106813939Slinton
106913939Slinton if( iclass == AUTO || iclass == REGISTER ){
107013939Slinton /* do the initialization and get out, without regard
107113939Slinton for filing out the variable with zeros, etc. */
107213939Slinton bccode();
107313939Slinton idname = pstk->in_id;
107413939Slinton p = buildtree( ASSIGN, buildtree( NAME, NIL, NIL ), p );
107513939Slinton ecomp(p);
107613939Slinton return;
107713939Slinton }
107813939Slinton
107913939Slinton if( p == NIL ) return; /* for throwing away strings that have been turned into lists */
108013939Slinton
108127247Sdonn if( ifull ){
108227247Sdonn uerror( "too many initializers" );
108327247Sdonn iclass = -1;
108427247Sdonn goto leave;
108527247Sdonn }
108613939Slinton if( ibseen ){
108713939Slinton uerror( "} expected");
108813939Slinton goto leave;
108913939Slinton }
109013939Slinton
109113939Slinton # ifndef BUG1
109213939Slinton if( idebug > 1 ) printf( "doinit(%o)\n", p );
109313939Slinton # endif
109413939Slinton
109513939Slinton t = pstk->in_t; /* type required */
109613939Slinton d = pstk->in_d;
109713939Slinton s = pstk->in_s;
109813939Slinton if( pstk->in_sz < 0 ){ /* bit field */
109913939Slinton sz = -pstk->in_sz;
110013939Slinton }
110113939Slinton else {
110213939Slinton sz = tsize( t, d, s );
110313939Slinton }
110413939Slinton
110513939Slinton inforce( pstk->in_off );
110613939Slinton
110713939Slinton p = buildtree( ASSIGN, block( NAME, NIL,NIL, t, d, s ), p );
110832824Sdonn #ifdef LINT
110932824Sdonn /* force lint to treat this like an assignment */
111032824Sdonn ecode(p);
111132824Sdonn #endif
111213939Slinton p->in.left->in.op = FREE;
111313939Slinton p->in.left = p->in.right;
111413939Slinton p->in.right = NIL;
111513939Slinton p->in.left = optim( p->in.left );
111617746Sralph o = p->in.left->in.op;
111717746Sralph if( o == UNARY AND ){
111817746Sralph o = p->in.left->in.op = FREE;
111913939Slinton p->in.left = p->in.left->in.left;
112013939Slinton }
112113939Slinton p->in.op = INIT;
112213939Slinton
112313939Slinton if( sz < SZINT ){ /* special case: bit fields, etc. */
112432815Sdonn if( o != ICON || p->in.left->tn.rval != NONAME )
112532815Sdonn uerror( "illegal initialization" );
112613939Slinton else incode( p->in.left, sz );
112713939Slinton }
112817746Sralph else if( o == FCON ){
112917746Sralph fincode( p->in.left->fpn.fval, sz );
113013939Slinton }
113117746Sralph else if( o == DCON ){
113217746Sralph fincode( p->in.left->dpn.dval, sz );
113317746Sralph }
113413939Slinton else {
113516178Sralph p = optim(p);
113616178Sralph if( p->in.left->in.op != ICON ) uerror( "illegal initialization" );
113716178Sralph else cinit( p, sz );
113813939Slinton }
113913939Slinton
114013939Slinton gotscal();
114113939Slinton
114213939Slinton leave:
114313939Slinton tfree(p);
114413939Slinton }
114513939Slinton
gotscal()114613939Slinton gotscal(){
114713939Slinton register t, ix;
114813939Slinton register n, id;
114913939Slinton struct symtab *p;
115013939Slinton OFFSZ temp;
115113939Slinton
115213939Slinton for( ; pstk > instack; ) {
115313939Slinton
115413939Slinton if( pstk->in_fl ) ++ibseen;
115513939Slinton
115613939Slinton --pstk;
115713939Slinton
115813939Slinton t = pstk->in_t;
115913939Slinton
116013939Slinton if( t == STRTY ){
116113939Slinton ix = ++pstk->in_x;
116213939Slinton if( (id=dimtab[ix]) < 0 ) continue;
116313939Slinton
116413939Slinton /* otherwise, put next element on the stack */
116513939Slinton
116613939Slinton p = &stab[id];
116713939Slinton instk( id, p->stype, p->dimoff, p->sizoff, p->offset+pstk->in_off );
116813939Slinton return;
116913939Slinton }
117013939Slinton else if( ISARY(t) ){
117113939Slinton n = ++pstk->in_n;
117213939Slinton if( n >= dimtab[pstk->in_d] && pstk > instack ) continue;
117313939Slinton
117413939Slinton /* put the new element onto the stack */
117513939Slinton
117613939Slinton temp = pstk->in_sz;
117713939Slinton instk( pstk->in_id, (TWORD)DECREF(pstk->in_t), pstk->in_d+1, pstk->in_s,
117813939Slinton pstk->in_off+n*temp );
117913939Slinton return;
118013939Slinton }
118113939Slinton
118213939Slinton }
118327247Sdonn ifull = 1;
118413939Slinton }
118513939Slinton
ilbrace()118613939Slinton ilbrace(){ /* process an initializer's left brace */
118713939Slinton register t;
118813939Slinton struct instk *temp;
118913939Slinton
119013939Slinton temp = pstk;
119113939Slinton
119213939Slinton for( ; pstk > instack; --pstk ){
119313939Slinton
119413939Slinton t = pstk->in_t;
119513939Slinton if( t != STRTY && !ISARY(t) ) continue; /* not an aggregate */
119613939Slinton if( pstk->in_fl ){ /* already associated with a { */
119713939Slinton if( pstk->in_n ) uerror( "illegal {");
119813939Slinton continue;
119913939Slinton }
120013939Slinton
120113939Slinton /* we have one ... */
120213939Slinton pstk->in_fl = 1;
120313939Slinton break;
120413939Slinton }
120513939Slinton
120613939Slinton /* cannot find one */
120713939Slinton /* ignore such right braces */
120813939Slinton
120913939Slinton pstk = temp;
121013939Slinton }
121113939Slinton
irbrace()121213939Slinton irbrace(){
121313939Slinton /* called when a '}' is seen */
121413939Slinton
121513939Slinton # ifndef BUG1
121613939Slinton if( idebug ) printf( "irbrace(): paramno = %d on entry\n", paramno );
121713939Slinton # endif
121813939Slinton
121913939Slinton if( ibseen ) {
122013939Slinton --ibseen;
122113939Slinton return;
122213939Slinton }
122313939Slinton
122413939Slinton for( ; pstk > instack; --pstk ){
122513939Slinton if( !pstk->in_fl ) continue;
122613939Slinton
122713939Slinton /* we have one now */
122813939Slinton
122913939Slinton pstk->in_fl = 0; /* cancel { */
123013939Slinton gotscal(); /* take it away... */
123113939Slinton return;
123213939Slinton }
123313939Slinton
123413939Slinton /* these right braces match ignored left braces: throw out */
123527247Sdonn ifull = 1;
123613939Slinton
123713939Slinton }
123813939Slinton
upoff(size,alignment,poff)123913939Slinton upoff( size, alignment, poff ) register alignment, *poff; {
124013939Slinton /* update the offset pointed to by poff; return the
124113939Slinton /* offset of a value of size `size', alignment `alignment',
124213939Slinton /* given that off is increasing */
124313939Slinton
124413939Slinton register off;
124513939Slinton
124613939Slinton off = *poff;
124713939Slinton SETOFF( off, alignment );
124813939Slinton if( (offsz-off) < size ){
124913939Slinton if( instruct!=INSTRUCT )cerror("too many local variables");
125013939Slinton else cerror("Structure too large");
125113939Slinton }
125213939Slinton *poff = off+size;
125313939Slinton return( off );
125413939Slinton }
125513939Slinton
oalloc(p,poff)125613939Slinton oalloc( p, poff ) register struct symtab *p; register *poff; {
125713939Slinton /* allocate p with offset *poff, and update *poff */
125813939Slinton register al, off, tsz;
125913939Slinton int noff;
126013939Slinton
126113939Slinton al = talign( p->stype, p->sizoff );
126213939Slinton noff = off = *poff;
126313939Slinton tsz = tsize( p->stype, p->dimoff, p->sizoff );
126413939Slinton #ifdef BACKAUTO
126513939Slinton if( p->sclass == AUTO ){
126613939Slinton if( (offsz-off) < tsz ) cerror("too many local variables");
126713939Slinton noff = off + tsz;
126813939Slinton SETOFF( noff, al );
126913939Slinton off = -noff;
127013939Slinton }
127113939Slinton else
127213939Slinton #endif
127313939Slinton if( p->sclass == PARAM && ( tsz < SZINT ) ){
127413939Slinton off = upoff( SZINT, ALINT, &noff );
127513939Slinton # ifndef RTOLBYTES
127613939Slinton off = noff - tsz;
127713939Slinton #endif
127813939Slinton }
127913939Slinton else
128013939Slinton {
128113939Slinton off = upoff( tsz, al, &noff );
128213939Slinton }
128313939Slinton
128413939Slinton if( p->sclass != REGISTER ){ /* in case we are allocating stack space for register arguments */
128513939Slinton if( p->offset == NOOFFSET ) p->offset = off;
128613939Slinton else if( off != p->offset ) return(1);
128713939Slinton }
128813939Slinton
128913939Slinton *poff = noff;
129013939Slinton return(0);
129113939Slinton }
129213939Slinton
falloc(p,w,new,pty)129313939Slinton falloc( p, w, new, pty ) register struct symtab *p; NODE *pty; {
129413939Slinton /* allocate a field of width w */
129513939Slinton /* new is 0 if new entry, 1 if redefinition, -1 if alignment */
129613939Slinton
129713939Slinton register al,sz,type;
129813939Slinton
129913939Slinton type = (new<0)? pty->in.type : p->stype;
130013939Slinton
130113939Slinton /* this must be fixed to use the current type in alignments */
130213939Slinton switch( new<0?pty->in.type:p->stype ){
130313939Slinton
130413939Slinton case ENUMTY:
130513939Slinton {
130613939Slinton int s;
130713939Slinton s = new<0 ? pty->fn.csiz : p->sizoff;
130813939Slinton al = dimtab[s+2];
130913939Slinton sz = dimtab[s];
131013939Slinton break;
131113939Slinton }
131213939Slinton
131313939Slinton case CHAR:
131413939Slinton case UCHAR:
131513939Slinton al = ALCHAR;
131613939Slinton sz = SZCHAR;
131713939Slinton break;
131813939Slinton
131913939Slinton case SHORT:
132013939Slinton case USHORT:
132113939Slinton al = ALSHORT;
132213939Slinton sz = SZSHORT;
132313939Slinton break;
132413939Slinton
132513939Slinton case INT:
132613939Slinton case UNSIGNED:
132713939Slinton al = ALINT;
132813939Slinton sz = SZINT;
132913939Slinton break;
133013939Slinton #ifdef LONGFIELDS
133113939Slinton
133213939Slinton case LONG:
133313939Slinton case ULONG:
133413939Slinton al = ALLONG;
133513939Slinton sz = SZLONG;
133613939Slinton break;
133713939Slinton #endif
133813939Slinton
133913939Slinton default:
134013939Slinton if( new < 0 ) {
134113939Slinton uerror( "illegal field type" );
134213939Slinton al = ALINT;
134313939Slinton }
134413939Slinton else {
134513939Slinton al = fldal( p->stype );
134613939Slinton sz =SZINT;
134713939Slinton }
134813939Slinton }
134913939Slinton
135013939Slinton if( w > sz ) {
135113939Slinton uerror( "field too big");
135213939Slinton w = sz;
135313939Slinton }
135413939Slinton
135513939Slinton if( w == 0 ){ /* align only */
135613939Slinton SETOFF( strucoff, al );
135713939Slinton if( new >= 0 ) uerror( "zero size field");
135813939Slinton return(0);
135913939Slinton }
136013939Slinton
136113939Slinton if( strucoff%al + w > sz ) SETOFF( strucoff, al );
136213939Slinton if( new < 0 ) {
136313939Slinton if( (offsz-strucoff) < w )
136413939Slinton cerror("structure too large");
136513939Slinton strucoff += w; /* we know it will fit */
136613939Slinton return(0);
136713939Slinton }
136813939Slinton
136913939Slinton /* establish the field */
137013939Slinton
137113939Slinton if( new == 1 ) { /* previous definition */
137213939Slinton if( p->offset != strucoff || p->sclass != (FIELD|w) ) return(1);
137313939Slinton }
137413939Slinton p->offset = strucoff;
137513939Slinton if( (offsz-strucoff) < w ) cerror("structure too large");
137613939Slinton strucoff += w;
137713939Slinton p->stype = type;
137813939Slinton fldty( p );
137913939Slinton return(0);
138013939Slinton }
138113939Slinton
nidcl(p)138213939Slinton nidcl( p ) NODE *p; { /* handle unitialized declarations */
138313939Slinton /* assumed to be not functions */
138413939Slinton register class;
138513939Slinton register commflag; /* flag for labelled common declarations */
138613939Slinton
138713939Slinton commflag = 0;
138813939Slinton
138913939Slinton /* compute class */
139013939Slinton if( (class=curclass) == SNULL ){
139113939Slinton if( blevel > 1 ) class = AUTO;
139213939Slinton else if( blevel != 0 || instruct ) cerror( "nidcl error" );
139313939Slinton else { /* blevel = 0 */
139413939Slinton class = noinit();
139513939Slinton if( class == EXTERN ) commflag = 1;
139613939Slinton }
139713939Slinton }
139813939Slinton #ifdef LCOMM
139932817Sdonn /* hack so stab will come out as LCSYM rather than STSYM */
140013939Slinton if (class == STATIC) {
140113939Slinton extern int stabLCSYM;
140213939Slinton stabLCSYM = 1;
140313939Slinton }
140413939Slinton #endif
140513939Slinton
140613939Slinton defid( p, class );
140713939Slinton
140832816Sdonn /* if an array is not initialized, no empty dimension */
140932820Sdonn if( class!=EXTERN && class!=TYPEDEF &&
141032820Sdonn ISARY(p->in.type) && dimtab[p->fn.cdim]==0 )
141132816Sdonn uerror("null storage definition");
141232816Sdonn
141313939Slinton #ifndef LCOMM
141424405Smckusick if( class==EXTDEF || class==STATIC )
141513939Slinton #else
141613939Slinton if (class==STATIC) {
141713939Slinton register struct symtab *s = &stab[p->tn.rval];
141813939Slinton extern int stabLCSYM;
141913939Slinton int sz = tsize(s->stype, s->dimoff, s->sizoff)/SZCHAR;
142013939Slinton
142113939Slinton stabLCSYM = 0;
142213939Slinton if (sz % sizeof (int))
142313939Slinton sz += sizeof (int) - (sz % sizeof (int));
142413939Slinton if (s->slevel > 1)
142513939Slinton printf(" .lcomm L%d,%d\n", s->offset, sz);
142613939Slinton else
142713939Slinton printf(" .lcomm %s,%d\n", exname(s->sname), sz);
142824405Smckusick }else if (class == EXTDEF)
142913939Slinton #endif
143024405Smckusick {
143113939Slinton /* simulate initialization by 0 */
143213939Slinton beginit(p->tn.rval);
143313939Slinton endinit();
143413939Slinton }
143513939Slinton if( commflag ) commdec( p->tn.rval );
143613939Slinton }
143713939Slinton
143813939Slinton TWORD
types(t1,t2,t3)143913939Slinton types( t1, t2, t3 ) TWORD t1, t2, t3; {
144013939Slinton /* return a basic type from basic types t1, t2, and t3 */
144113939Slinton
144213939Slinton TWORD t[3], noun, adj, unsg;
144313939Slinton register i;
144413939Slinton
144513939Slinton t[0] = t1;
144613939Slinton t[1] = t2;
144713939Slinton t[2] = t3;
144813939Slinton
144913939Slinton unsg = INT; /* INT or UNSIGNED */
145013939Slinton noun = UNDEF; /* INT, CHAR, or FLOAT */
145113939Slinton adj = INT; /* INT, LONG, or SHORT */
145213939Slinton
145313939Slinton for( i=0; i<3; ++i ){
145413939Slinton switch( t[i] ){
145513939Slinton
145613939Slinton default:
145713939Slinton bad:
145813939Slinton uerror( "illegal type combination" );
145913939Slinton return( INT );
146013939Slinton
146113939Slinton case UNDEF:
146213939Slinton continue;
146313939Slinton
146413939Slinton case UNSIGNED:
146513939Slinton if( unsg != INT ) goto bad;
146613939Slinton unsg = UNSIGNED;
146713939Slinton continue;
146813939Slinton
146913939Slinton case LONG:
147013939Slinton case SHORT:
147113939Slinton if( adj != INT ) goto bad;
147213939Slinton adj = t[i];
147313939Slinton continue;
147413939Slinton
147513939Slinton case INT:
147613939Slinton case CHAR:
147713939Slinton case FLOAT:
147813939Slinton if( noun != UNDEF ) goto bad;
147913939Slinton noun = t[i];
148013939Slinton continue;
148113939Slinton }
148213939Slinton }
148313939Slinton
148413939Slinton /* now, construct final type */
148513939Slinton if( noun == UNDEF ) noun = INT;
148613939Slinton else if( noun == FLOAT ){
148713939Slinton if( unsg != INT || adj == SHORT ) goto bad;
148813939Slinton return( adj==LONG ? DOUBLE : FLOAT );
148913939Slinton }
149013939Slinton else if( noun == CHAR && adj != INT ) goto bad;
149113939Slinton
149213939Slinton /* now, noun is INT or CHAR */
149313939Slinton if( adj != INT ) noun = adj;
149413939Slinton if( unsg == UNSIGNED ) return( noun + (UNSIGNED-INT) );
149513939Slinton else return( noun );
149613939Slinton }
149713939Slinton
149813939Slinton NODE *
tymerge(typ,idp)149913939Slinton tymerge( typ, idp ) NODE *typ, *idp; {
150013939Slinton /* merge type typ with identifier idp */
150113939Slinton
150213939Slinton register unsigned t;
150313939Slinton register i;
150413939Slinton extern int eprint();
150513939Slinton
150613939Slinton if( typ->in.op != TYPE ) cerror( "tymerge: arg 1" );
150713939Slinton if(idp == NIL ) return( NIL );
150813939Slinton
150913939Slinton # ifndef BUG1
151013939Slinton if( ddebug > 2 ) fwalk( idp, eprint, 0 );
151113939Slinton # endif
151213939Slinton
151313939Slinton idp->in.type = typ->in.type;
151413939Slinton idp->fn.cdim = curdim;
151513939Slinton tyreduce( idp );
151613939Slinton idp->fn.csiz = typ->fn.csiz;
151713939Slinton
151813939Slinton for( t=typ->in.type, i=typ->fn.cdim; t&TMASK; t = DECREF(t) ){
151913939Slinton if( ISARY(t) ) dstash( dimtab[i++] );
152013939Slinton }
152113939Slinton
152213939Slinton /* now idp is a single node: fix up type */
152313939Slinton
152413939Slinton idp->in.type = ctype( idp->in.type );
152513939Slinton
152613939Slinton if( (t = BTYPE(idp->in.type)) != STRTY && t != UNIONTY && t != ENUMTY ){
152713939Slinton idp->fn.csiz = t; /* in case ctype has rewritten things */
152813939Slinton }
152913939Slinton
153013939Slinton return( idp );
153113939Slinton }
153213939Slinton
tyreduce(p)153313939Slinton tyreduce( p ) register NODE *p; {
153413939Slinton
153513939Slinton /* build a type, and stash away dimensions, from a parse tree of the declaration */
153613939Slinton /* the type is build top down, the dimensions bottom up */
153713939Slinton register o, temp;
153813939Slinton register unsigned t;
153913939Slinton
154013939Slinton o = p->in.op;
154113939Slinton p->in.op = FREE;
154213939Slinton
154313939Slinton if( o == NAME ) return;
154413939Slinton
154513939Slinton t = INCREF( p->in.type );
154613939Slinton if( o == UNARY CALL ) t += (FTN-PTR);
154713939Slinton else if( o == LB ){
154813939Slinton t += (ARY-PTR);
154913939Slinton temp = p->in.right->tn.lval;
155013939Slinton p->in.right->in.op = FREE;
155132816Sdonn if( temp == 0 && p->in.left->tn.op == LB )
155232816Sdonn uerror( "null dimension" );
155313939Slinton }
155413939Slinton
155513939Slinton p->in.left->in.type = t;
155613939Slinton tyreduce( p->in.left );
155713939Slinton
155813939Slinton if( o == LB ) dstash( temp );
155913939Slinton
156013939Slinton p->tn.rval = p->in.left->tn.rval;
156113939Slinton p->in.type = p->in.left->in.type;
156213939Slinton
156313939Slinton }
156413939Slinton
fixtype(p,class)156513939Slinton fixtype( p, class ) register NODE *p; {
156613939Slinton register unsigned t, type;
156713939Slinton register mod1, mod2;
156813939Slinton /* fix up the types, and check for legality */
156913939Slinton
157013939Slinton if( (type = p->in.type) == UNDEF ) return;
157113939Slinton if( mod2 = (type&TMASK) ){
157213939Slinton t = DECREF(type);
157313939Slinton while( mod1=mod2, mod2 = (t&TMASK) ){
157413939Slinton if( mod1 == ARY && mod2 == FTN ){
157513939Slinton uerror( "array of functions is illegal" );
157613939Slinton type = 0;
157713939Slinton }
157813939Slinton else if( mod1 == FTN && ( mod2 == ARY || mod2 == FTN ) ){
157913939Slinton uerror( "function returns illegal type" );
158013939Slinton type = 0;
158113939Slinton }
158213939Slinton t = DECREF(t);
158313939Slinton }
158413939Slinton }
158513939Slinton
158613939Slinton /* detect function arguments, watching out for structure declarations */
158732816Sdonn /* for example, beware of f(x) struct { int a[10]; } *x; { ... } */
158813939Slinton /* the danger is that "a" will be converted to a pointer */
158913939Slinton
159032816Sdonn if( class==SNULL && blevel==1 && !(instruct&(INSTRUCT|INUNION)) )
159132816Sdonn class = PARAM;
159213939Slinton if( class == PARAM || ( class==REGISTER && blevel==1 ) ){
159313939Slinton if( type == FLOAT ) type = DOUBLE;
159413939Slinton else if( ISARY(type) ){
159532816Sdonn #ifdef LINT
159632816Sdonn if( hflag && dimtab[p->fn.cdim]!=0 )
159732816Sdonn werror("array[%d] type changed to pointer",
159832816Sdonn dimtab[p->fn.cdim]);
159932816Sdonn #endif
160013939Slinton ++p->fn.cdim;
160113939Slinton type += (PTR-ARY);
160213939Slinton }
160313939Slinton else if( ISFTN(type) ){
160413939Slinton werror( "a function is declared as an argument" );
160513939Slinton type = INCREF(type);
160613939Slinton }
160713939Slinton
160813939Slinton }
160913939Slinton
161013939Slinton if( instruct && ISFTN(type) ){
161113939Slinton uerror( "function illegal in structure or union" );
161213939Slinton type = INCREF(type);
161313939Slinton }
161413939Slinton p->in.type = type;
161513939Slinton }
161613939Slinton
uclass(class)161713939Slinton uclass( class ) register class; {
161813939Slinton /* give undefined version of class */
161913939Slinton if( class == SNULL ) return( EXTERN );
162013939Slinton else if( class == STATIC ) return( USTATIC );
162113939Slinton else if( class == FORTRAN ) return( UFORTRAN );
162213939Slinton else return( class );
162313939Slinton }
162413939Slinton
fixclass(class,type)162513939Slinton fixclass( class, type ) TWORD type; {
162613939Slinton
162713939Slinton /* first, fix null class */
162813939Slinton
162913939Slinton if( class == SNULL ){
163013939Slinton if( instruct&INSTRUCT ) class = MOS;
163113939Slinton else if( instruct&INUNION ) class = MOU;
163213939Slinton else if( blevel == 0 ) class = EXTDEF;
163313939Slinton else if( blevel == 1 ) class = PARAM;
163413939Slinton else class = AUTO;
163513939Slinton
163613939Slinton }
163713939Slinton
163813939Slinton /* now, do general checking */
163913939Slinton
164013939Slinton if( ISFTN( type ) ){
164113939Slinton switch( class ) {
164213939Slinton default:
164313939Slinton uerror( "function has illegal storage class" );
164413939Slinton case AUTO:
164513939Slinton class = EXTERN;
164613939Slinton case EXTERN:
164713939Slinton case EXTDEF:
164813939Slinton case FORTRAN:
164913939Slinton case TYPEDEF:
165013939Slinton case STATIC:
165113939Slinton case UFORTRAN:
165213939Slinton case USTATIC:
165313939Slinton ;
165413939Slinton }
165513939Slinton }
165613939Slinton
165713939Slinton if( class&FIELD ){
165813939Slinton if( !(instruct&INSTRUCT) ) uerror( "illegal use of field" );
165913939Slinton return( class );
166013939Slinton }
166113939Slinton
166213939Slinton switch( class ){
166313939Slinton
166413939Slinton case MOU:
166513939Slinton if( !(instruct&INUNION) ) uerror( "illegal class" );
166613939Slinton return( class );
166713939Slinton
166813939Slinton case MOS:
166913939Slinton if( !(instruct&INSTRUCT) ) uerror( "illegal class" );
167013939Slinton return( class );
167113939Slinton
167213939Slinton case MOE:
167313939Slinton if( instruct & (INSTRUCT|INUNION) ) uerror( "illegal class" );
167413939Slinton return( class );
167513939Slinton
167613939Slinton case REGISTER:
167713939Slinton if( blevel == 0 ) uerror( "illegal register declaration" );
167813939Slinton else if( regvar >= MINRVAR && cisreg( type ) ) return( class );
167913939Slinton if( blevel == 1 ) return( PARAM );
168013939Slinton else return( AUTO );
168113939Slinton
168213939Slinton case AUTO:
168313939Slinton case LABEL:
168413939Slinton case ULABEL:
168513939Slinton if( blevel < 2 ) uerror( "illegal class" );
168613939Slinton return( class );
168713939Slinton
168813939Slinton case PARAM:
168913939Slinton if( blevel != 1 ) uerror( "illegal class" );
169013939Slinton return( class );
169113939Slinton
169213939Slinton case UFORTRAN:
169313939Slinton case FORTRAN:
169413939Slinton # ifdef NOFORTRAN
169513939Slinton NOFORTRAN; /* a condition which can regulate the FORTRAN usage */
169613939Slinton # endif
169713939Slinton if( !ISFTN(type) ) uerror( "fortran declaration must apply to function" );
169813939Slinton else {
169913939Slinton type = DECREF(type);
170013939Slinton if( ISFTN(type) || ISARY(type) || ISPTR(type) ) {
170113939Slinton uerror( "fortran function has wrong type" );
170213939Slinton }
170313939Slinton }
170413939Slinton case EXTERN:
170513939Slinton case STATIC:
170613939Slinton case EXTDEF:
170713939Slinton case TYPEDEF:
170813939Slinton case USTATIC:
170917151Sralph if( blevel == 1 ){
171017151Sralph uerror( "illegal class" );
171117151Sralph return( PARAM );
171217151Sralph }
171317151Sralph case STNAME:
171417151Sralph case UNAME:
171517151Sralph case ENAME:
171613939Slinton return( class );
171713939Slinton
171813939Slinton default:
171913939Slinton cerror( "illegal class: %d", class );
172013939Slinton /* NOTREACHED */
172113939Slinton
172213939Slinton }
172313939Slinton }
172413939Slinton
172513939Slinton struct symtab *
mknonuniq(idindex)172613939Slinton mknonuniq(idindex) int *idindex; {/* locate a symbol table entry for */
172713939Slinton /* an occurrence of a nonunique structure member name */
172813939Slinton /* or field */
172913939Slinton register i;
173013939Slinton register struct symtab * sp;
173132817Sdonn char *q;
173213939Slinton
173313939Slinton sp = & stab[ i= *idindex ]; /* position search at old entry */
173413939Slinton while( sp->stype != TNULL ){ /* locate unused entry */
173513939Slinton if( ++i >= SYMTSZ ){/* wrap around symbol table */
173613939Slinton i = 0;
173713939Slinton sp = stab;
173813939Slinton }
173913939Slinton else ++sp;
174013939Slinton if( i == *idindex ) cerror("Symbol table full");
174113939Slinton }
174213939Slinton sp->sflags = SNONUNIQ | SMOS;
174313939Slinton q = stab[*idindex].sname; /* old entry name */
174413939Slinton #ifdef FLEXNAMES
174513939Slinton sp->sname = stab[*idindex].sname;
174613939Slinton #endif
174713939Slinton # ifndef BUG1
174813939Slinton if( ddebug ){
174913939Slinton printf("\tnonunique entry for %s from %d to %d\n",
175013939Slinton q, *idindex, i );
175113939Slinton }
175213939Slinton # endif
175313939Slinton *idindex = i;
175413939Slinton #ifndef FLEXNAMES
175532817Sdonn {
175632817Sdonn char *p = sp->sname;
175732817Sdonn for( i=1; i<=NCHNAM; ++i ) /* copy name */
175832817Sdonn if( *p++ = *q /* assign */ ) ++q;
175913939Slinton }
176013939Slinton #endif
176113939Slinton return ( sp );
176213939Slinton }
176313939Slinton
lookup(name,s)176413939Slinton lookup( name, s) char *name; {
176513939Slinton /* look up name: must agree with s w.r.t. STAG, SMOS and SHIDDEN */
176613939Slinton
176713939Slinton register char *p, *q;
176832817Sdonn int i, ii;
176932817Sdonn #ifndef FLEXNAMES
177032817Sdonn int j;
177132817Sdonn #endif
177213939Slinton register struct symtab *sp;
177313939Slinton
177413939Slinton /* compute initial hash index */
177513939Slinton # ifndef BUG1
177613939Slinton if( ddebug > 2 ){
177713939Slinton printf( "lookup( %s, %d ), stwart=%d, instruct=%d\n", name, s, stwart, instruct );
177813939Slinton }
177913939Slinton # endif
178013939Slinton
178113939Slinton i = 0;
178213939Slinton #ifndef FLEXNAMES
178313939Slinton for( p=name, j=0; *p != '\0'; ++p ){
178413939Slinton i += *p;
178513939Slinton if( ++j >= NCHNAM ) break;
178613939Slinton }
178713939Slinton #else
178813939Slinton i = (int)name;
178913939Slinton #endif
179013939Slinton i = i%SYMTSZ;
179113939Slinton sp = &stab[ii=i];
179213939Slinton
179313939Slinton for(;;){ /* look for name */
179413939Slinton
179513939Slinton if( sp->stype == TNULL ){ /* empty slot */
179613939Slinton sp->sflags = s; /* set STAG, SMOS if needed, turn off all others */
179713939Slinton #ifndef FLEXNAMES
179813939Slinton p = sp->sname;
179913939Slinton for( j=0; j<NCHNAM; ++j ) if( *p++ = *name ) ++name;
180013939Slinton #else
180113939Slinton sp->sname = name;
180213939Slinton #endif
180313939Slinton sp->stype = UNDEF;
180413939Slinton sp->sclass = SNULL;
180513939Slinton return( i );
180613939Slinton }
180713939Slinton if( (sp->sflags & (STAG|SMOS|SHIDDEN)) != s ) goto next;
180813939Slinton p = sp->sname;
180913939Slinton q = name;
181013939Slinton #ifndef FLEXNAMES
181113939Slinton for( j=0; j<NCHNAM;++j ){
181213939Slinton if( *p++ != *q ) goto next;
181313939Slinton if( !*q++ ) break;
181413939Slinton }
181513939Slinton return( i );
181613939Slinton #else
181713939Slinton if (p == q)
181813939Slinton return ( i );
181913939Slinton #endif
182013939Slinton next:
182113939Slinton if( ++i >= SYMTSZ ){
182213939Slinton i = 0;
182313939Slinton sp = stab;
182413939Slinton }
182513939Slinton else ++sp;
182613939Slinton if( i == ii ) cerror( "symbol table full" );
182713939Slinton }
182813939Slinton }
182913939Slinton
183013939Slinton #ifndef checkst
183113939Slinton /* if not debugging, make checkst a macro */
checkst(lev)183213939Slinton checkst(lev){
183313939Slinton register int s, i, j;
183413939Slinton register struct symtab *p, *q;
183513939Slinton
183613939Slinton for( i=0, p=stab; i<SYMTSZ; ++i, ++p ){
183713939Slinton if( p->stype == TNULL ) continue;
183813939Slinton j = lookup( p->sname, p->sflags&(SMOS|STAG) );
183913939Slinton if( j != i ){
184013939Slinton q = &stab[j];
184113939Slinton if( q->stype == UNDEF ||
184213939Slinton q->slevel <= p->slevel ){
184313939Slinton #ifndef FLEXNAMES
184413939Slinton cerror( "check error: %.8s", q->sname );
184513939Slinton #else
184613939Slinton cerror( "check error: %s", q->sname );
184713939Slinton #endif
184813939Slinton }
184913939Slinton }
185013939Slinton #ifndef FLEXNAMES
185113939Slinton else if( p->slevel > lev ) cerror( "%.8s check at level %d", p->sname, lev );
185213939Slinton #else
185313939Slinton else if( p->slevel > lev ) cerror( "%s check at level %d", p->sname, lev );
185413939Slinton #endif
185513939Slinton }
185613939Slinton }
185713939Slinton #endif
185813939Slinton
185913939Slinton struct symtab *
relook(p)186013939Slinton relook(p) register struct symtab *p; { /* look up p again, and see where it lies */
186113939Slinton
186213939Slinton register struct symtab *q;
186313939Slinton
186413939Slinton /* I'm not sure that this handles towers of several hidden definitions in all cases */
186513939Slinton q = &stab[lookup( p->sname, p->sflags&(STAG|SMOS|SHIDDEN) )];
186613939Slinton /* make relook always point to either p or an empty cell */
186713939Slinton if( q->stype == UNDEF ){
186813939Slinton q->stype = TNULL;
186913939Slinton return(q);
187013939Slinton }
187113939Slinton while( q != p ){
187213939Slinton if( q->stype == TNULL ) break;
187313939Slinton if( ++q >= &stab[SYMTSZ] ) q=stab;
187413939Slinton }
187513939Slinton return(q);
187613939Slinton }
187713939Slinton
clearst(lev)187824405Smckusick clearst( lev ) register int lev; {
187924405Smckusick register struct symtab *p, *q;
188024405Smckusick register int temp;
188124405Smckusick struct symtab *clist = 0;
188213939Slinton
188313939Slinton temp = lineno;
188413939Slinton aobeg();
188513939Slinton
188624405Smckusick /* step 1: remove entries */
188724405Smckusick while( chaintop-1 > lev ){
188824405Smckusick p = schain[--chaintop];
188924405Smckusick schain[chaintop] = 0;
189024405Smckusick for( ; p; p = q ){
189124405Smckusick q = p->snext;
189224405Smckusick if( p->stype == TNULL || p->slevel <= lev )
189324405Smckusick cerror( "schain botch" );
189424405Smckusick lineno = p->suse < 0 ? -p->suse : p->suse;
189524405Smckusick if( p->stype==UNDEF || ( p->sclass==ULABEL && lev<2 ) ){
189613939Slinton lineno = temp;
189713939Slinton #ifndef FLEXNAMES
189813939Slinton uerror( "%.8s undefined", p->sname );
189913939Slinton #else
190013939Slinton uerror( "%s undefined", p->sname );
190113939Slinton #endif
190213939Slinton }
190313939Slinton else aocode(p);
190413939Slinton # ifndef BUG1
190524405Smckusick if( ddebug ){
190613939Slinton #ifndef FLEXNAMES
190724405Smckusick printf( "removing %.8s", p->sname );
190813939Slinton #else
190924405Smckusick printf( "removing %s", p->sname );
191013939Slinton #endif
191124405Smckusick printf( " from stab[%d], flags %o level %d\n",
191224405Smckusick p-stab, p->sflags, p->slevel);
191324405Smckusick }
191413939Slinton # endif
191524405Smckusick if( p->sflags & SHIDES )unhide( p );
191613939Slinton p->stype = TNULL;
191724405Smckusick p->snext = clist;
191824405Smckusick clist = p;
191913939Slinton }
192024405Smckusick }
192124405Smckusick
192224405Smckusick /* step 2: fix any mishashed entries */
192324405Smckusick p = clist;
192424405Smckusick while( p ){
192532825Sdonn register struct symtab *next, **t, *r;
192624405Smckusick
192724405Smckusick q = p;
192827247Sdonn next = p->snext;
192924405Smckusick for(;;){
193024405Smckusick if( ++q >= &stab[SYMTSZ] )q = stab;
193124405Smckusick if( q == p || q->stype == TNULL )break;
193224405Smckusick if( (r = relook(q)) != q ) {
193332822Sdonn /* move q in schain list */
193432825Sdonn t = &schain[q->slevel];
193532825Sdonn while( *t && *t != q )
193632825Sdonn t = &(*t)->snext;
193732825Sdonn if( *t )
193832825Sdonn *t = r;
193932825Sdonn else
194032823Sdonn cerror("schain botch 2");
194124405Smckusick *r = *q;
194226822Sdonn q->stype = TNULL;
194313939Slinton }
194413939Slinton }
194527247Sdonn p = next;
194613939Slinton }
194724405Smckusick
194813939Slinton lineno = temp;
194913939Slinton aoend();
195013939Slinton }
195113939Slinton
hide(p)195213939Slinton hide( p ) register struct symtab *p; {
195313939Slinton register struct symtab *q;
195413939Slinton for( q=p+1; ; ++q ){
195513939Slinton if( q >= &stab[SYMTSZ] ) q = stab;
195613939Slinton if( q == p ) cerror( "symbol table full" );
195713939Slinton if( q->stype == TNULL ) break;
195813939Slinton }
195924405Smckusick *q = *p;
196013939Slinton p->sflags |= SHIDDEN;
196113939Slinton q->sflags = (p->sflags&(SMOS|STAG)) | SHIDES;
196213939Slinton #ifndef FLEXNAMES
196313939Slinton if( hflag ) werror( "%.8s redefinition hides earlier one", p->sname );
196413939Slinton #else
196513939Slinton if( hflag ) werror( "%s redefinition hides earlier one", p->sname );
196613939Slinton #endif
196713939Slinton # ifndef BUG1
196813939Slinton if( ddebug ) printf( " %d hidden in %d\n", p-stab, q-stab );
196913939Slinton # endif
197013939Slinton return( idname = q-stab );
197113939Slinton }
197213939Slinton
unhide(p)197313939Slinton unhide( p ) register struct symtab *p; {
197413939Slinton register struct symtab *q;
197532817Sdonn register s;
197613939Slinton
197713939Slinton s = p->sflags & (SMOS|STAG);
197813939Slinton q = p;
197913939Slinton
198013939Slinton for(;;){
198113939Slinton
198213939Slinton if( q == stab ) q = &stab[SYMTSZ-1];
198313939Slinton else --q;
198413939Slinton
198513939Slinton if( q == p ) break;
198613939Slinton
198713939Slinton if( (q->sflags&(SMOS|STAG)) == s ){
198813939Slinton #ifndef FLEXNAMES
198932817Sdonn register j;
199013939Slinton for( j =0; j<NCHNAM; ++j ) if( p->sname[j] != q->sname[j] ) break;
199113939Slinton if( j == NCHNAM ){ /* found the name */
199213939Slinton #else
199313939Slinton if (p->sname == q->sname) {
199413939Slinton #endif
199513939Slinton q->sflags &= ~SHIDDEN;
199613939Slinton # ifndef BUG1
199713939Slinton if( ddebug ) printf( "unhide uncovered %d from %d\n", q-stab,p-stab);
199813939Slinton # endif
199913939Slinton return;
200013939Slinton }
200113939Slinton }
200213939Slinton
200313939Slinton }
200413939Slinton cerror( "unhide fails" );
200513939Slinton }
2006