📄 pftn.c
字号:
pstk = instack; t = pstk->in_t; d = pstk->in_d; s = pstk->in_s; n = pstk->in_n; if( ISARY(t) ){ d1 = dimtab[d]; vfdalign( pstk->in_sz ); /* fill out part of the last element, if needed */ n = inoff/pstk->in_sz; /* real number of initializers */ if( d1 >= n ){ /* once again, t is an array, so no fields */ inforce( tsize( t, d, s ) ); n = d1; } if( d1!=0 && d1!=n ) uerror( "too many initializers"); if( n==0 ) werror( "empty array declaration"); dimtab[d] = n; if( d1==0 ) FIXDEF(&stab[pstk->in_id]); } else if( t == STRTY || t == UNIONTY ){ /* clearly not fields either */ inforce( tsize( t, d, s ) ); } else if( n > 1 ) uerror( "bad scalar initialization"); /* this will never be called with a field element... */ else inforce( tsize(t,d,s) ); paramno = 0; vfdalign( AL_INIT ); inoff = 0; iclass = SNULL; }doinit( p ) register NODE *p; { /* take care of generating a value for the initializer p */ /* inoff has the current offset (last bit written) in the current word being generated */ register sz, d, s; register TWORD t; /* note: size of an individual initializer is assumed to fit into an int */ if( iclass < 0 ) goto leave; if( iclass == EXTERN || iclass == UNAME ){ uerror( "cannot initialize extern or union" ); iclass = -1; goto leave; } if( iclass == AUTO || iclass == REGISTER ){ /* do the initialization and get out, without regard for filing out the variable with zeros, etc. */ bccode(); idname = pstk->in_id; p = buildtree( INITASSIGN, buildtree( NAME, NIL, NIL ), p ); ecomp(p); return; } if( p == NIL ) return; /* for throwing away strings that have been turned into lists */ if( ibseen ){ uerror( "} expected"); goto leave; }# ifndef BUG1 if( idebug > 1 ) printf( "doinit(%o)\n", p );# endif t = pstk->in_t; /* type required */ d = pstk->in_d; s = pstk->in_s; if( pstk->in_sz < 0 ){ /* bit field */ sz = -pstk->in_sz; } else { sz = tsize( t, d, s ); } inforce( pstk->in_off ); p = buildtree( INITASSIGN, block( NAME, NIL,NIL, t, d, s ), p ); p->in.left->in.op = FREE; p->in.left = p->in.right; p->in.right = NIL; p->in.left = optim( p->in.left ); if( p->in.left->in.op == UNARY AND ){ p->in.left->in.op = FREE; p->in.left = p->in.left->in.left; } p->in.op = INIT; if( sz < SZINT ){ /* special case: bit fields, etc. */ if( p->in.left->in.op != ICON ) uerror( "illegal initialization" ); else incode( p->in.left, sz ); } /* vdp - distinguish between double constants * and single constants */ else if( p->in.left->in.op == FCON ){ fincode( p->in.left->fpn.fval, sz ); } else if(p->in.left->in.op == DCON ) { fincode( p->in.left->dpn.dval, sz ); } else { /* * SLR002 * Becuase of the way the tables are set-up for * the INIT node the code generator will loop * forever until internal table are full. This * test to see if the left node is an integer * will insure that we will not get in the case * where we loop. */ if ( optim(p)->in.left->in.op != ICON ) { /* * SL001 * We are not an integer so emit an error * and leave. This condition will prevent * us goin to the code generator with a * tree that it can not reduce */ uerror ( "illegal initialization"); goto leave; } else /* * Produce the initialization code */ cinit( p, sz ); } gotscal(); leave: tfree(p); }gotscal(){ register t, ix; register n, id; struct symtab *p; OFFSZ temp; for( ; pstk > instack; ) { if( pstk->in_fl ) ++ibseen; --pstk; t = pstk->in_t; if( t == STRTY ){ ix = ++pstk->in_x; if( (id=dimtab[ix]) < 0 ) continue; /* otherwise, put next element on the stack */ p = &stab[id]; instk( id, p->stype, p->dimoff, p->sizoff, p->offset+pstk->in_off ); return; } else if( ISARY(t) ){ n = ++pstk->in_n; if( n >= dimtab[pstk->in_d] && pstk > instack ) continue; /* put the new element onto the stack */ temp = pstk->in_sz; instk( pstk->in_id, (TWORD)DECREF(pstk->in_t), pstk->in_d+1, pstk->in_s, pstk->in_off+n*temp ); return; } } }ilbrace(){ /* process an initializer's left brace */ register t; struct instk *temp; temp = pstk; for( ; pstk > instack; --pstk ){ t = pstk->in_t; if( t != STRTY && !ISARY(t) ) continue; /* not an aggregate */ if( pstk->in_fl ){ /* already associated with a { */ if( pstk->in_n ) uerror( "illegal {"); continue; } /* we have one ... */ pstk->in_fl = 1; break; } /* cannot find one */ /* ignore such right braces */ pstk = temp; }irbrace(){ /* called when a '}' is seen */# ifndef BUG1 if( idebug ) printf( "irbrace(): paramno = %d on entry\n", paramno );# endif if( ibseen ) { --ibseen; return; } for( ; pstk > instack; --pstk ){ if( !pstk->in_fl ) continue; /* we have one now */ pstk->in_fl = 0; /* cancel { */ gotscal(); /* take it away... */ return; } /* these right braces match ignored left braces: throw out */ }upoff( size, alignment, poff ) register alignment, *poff; { /* update the offset pointed to by poff; return the /* offset of a value of size `size', alignment `alignment', /* given that off is increasing */ register off; off = *poff; SETOFF( off, alignment ); if( (offsz-off) < size ){ if( instruct!=INSTRUCT )cerror("too many local variables"); else cerror("Structure too large"); } *poff = off+size; return( off ); }oalloc( p, poff ) register struct symtab *p; register *poff; { /* allocate p with offset *poff, and update *poff */ register al, off, tsz; int noff; al = talign( p->stype, p->sizoff ); noff = off = *poff; tsz = tsize( p->stype, p->dimoff, p->sizoff );#ifdef BACKAUTO if( p->sclass == AUTO ){ if( (offsz-off) < tsz ) cerror("too many local variables"); noff = off + tsz; SETOFF( noff, al ); off = -noff; } else#endif if( p->sclass == PARAM && ( tsz < SZINT ) ){ off = upoff( SZINT, ALINT, &noff );# ifndef RTOLBYTES off = noff - tsz;#endif } else { off = upoff( tsz, al, &noff ); } if( p->sclass != REGISTER ){ /* in case we are allocating stack space for register arguments */ if( p->offset == NOOFFSET ) p->offset = off; else if( off != p->offset ) return(1); } *poff = noff; return(0); }falloc( p, w, new, pty ) register struct symtab *p; NODE *pty; { /* allocate a field of width w */ /* new is 0 if new entry, 1 if redefinition, -1 if alignment */ register al,sz,type; type = (new<0)? pty->in.type : p->stype; /* this must be fixed to use the current type in alignments */ switch( new<0?pty->in.type:p->stype ){ case ENUMTY: { int s; s = new<0 ? pty->fn.csiz : p->sizoff; al = dimtab[s+2]; sz = dimtab[s]; break; } case CHAR: case UCHAR: al = ALCHAR; sz = SZCHAR; break; case SHORT: case USHORT: al = ALSHORT; sz = SZSHORT; break; case INT: case UNSIGNED: al = ALINT; sz = SZINT; break;#ifdef LONGFIELDS case LONG: case ULONG: al = ALLONG; sz = SZLONG; break;#endif default: if( new < 0 ) { uerror( "illegal field type" ); al = ALINT; } else { al = fldal( p->stype ); sz =SZINT; } } if( w > sz ) { uerror( "field too big"); w = sz; } if( w == 0 ){ /* align only */ SETOFF( strucoff, al ); if( new >= 0 ) uerror( "zero size field"); return(0); } if( strucoff%al + w > sz ) SETOFF( strucoff, al ); if( new < 0 ) { if( (offsz-strucoff) < w ) cerror("structure too large"); strucoff += w; /* we know it will fit */ return(0); } /* establish the field */ if( new == 1 ) { /* previous definition */ if( p->offset != strucoff || p->sclass != (FIELD|w) ) return(1); } p->offset = strucoff; if( (offsz-strucoff) < w ) cerror("structure too large"); strucoff += w; p->stype = type; fldty( p ); return(0);}nidcl( p ) NODE *p; { /* handle unitialized declarations */ /* assumed to be not functions */ register class; register commflag; /* flag for labelled common declarations */ struct symtab * q; OFFSZ tsize(); OFFSZ off; commflag = 0; /* compute class */ if( (class=curclass) == SNULL ){ if( blevel > 1 ) class = AUTO; else if( blevel != 0 || instruct ) cerror( "nidcl error" ); else { /* blevel = 0 */ class = noinit(); if( class == EXTERN ) commflag = 1; } }#ifdef LCOMM /* hack so stab will come at as LCSYM rather than STSYM */ if (class == STATIC) { extern int stabLCSYM; stabLCSYM = 1; }#endif defid( p, class );#ifndef LCOMM if( class==EXTDEF || class==STATIC ){#else if (class==STATIC) { register struct symtab *s = &stab[p->tn.rval]; extern int stabLCSYM; int sz = tsize(s->stype, s->dimoff, s->sizoff)/SZCHAR; stabLCSYM = 0; if (sz % sizeof (int)) sz += sizeof (int) - (sz % sizeof (int)); if (s->slevel > 1) printf(" .lcomm L%d,%d\n", s->offset, sz); else printf(" .lcomm %s,%d\n", exname(s->sname), sz); }else if (class == EXTDEF) {#endif /* simulate initialization by 0 */ beginit(p->tn.rval); endinit(); } if( commflag ) commdec( p->tn.rval );/* jpm: Resolve qar 5458, detect incomplete array types and complain... * eg: main(){ int i; char bozo[]; i = 3} * the size of bozo is unknown so we must admonish the user */ q = &stab[p->tn.rval]; if ( (class == AUTO) && ISARY(q->stype) ) { off = tsize( q->stype, q->dimoff, q->sizoff); off /= SZCHAR; if ( off == 0) werror("size of array %s is required unless 'extern' specified", q->sname); };}types( p )NODE *p;{ /* Merge several basic types (eg. unsigned const long int) into * one consolidated type (eg. ULONG). The type nodes are linked * together as left children. NIL signifies end of the list. * * This routine should only be called when there is more than * one type. Eg., " Boolean b; ", where Boolean is a typedef, * should not be evaluated by this routine. Boolean has already * been seen in the typedef declaration; this routine would get * ENUMTY for the type and assume an invalid type declaration. * Remember - types() only understands *basic* types. * See manifest for a list of basic type definitions. */ NODE *t; TWORD noun, adj, unsg, cvattr; register int i; unsg = INT; /* INT or UNSIGNED */ noun = UNDEF; /* INT, CHAR, FLOAT, or DOUBLE */ adj = INT; /* INT, LONG, or SHORT */ cvattr = 0; for (t = p; t != NIL; t = t->in.left) { if (t != p) t->in.op = FREE; switch( t->in.type ) { default: bad: uerror( "illegal type combination" ); return( INT ); case UNDEF: continue; case UNSIGNED: if( unsg != INT ) goto bad; unsg = UNSIGNED; continue; case CONST: /* const declaration */ cvattr |= BCONST; /* set const bit */ continue; case VOLATILE: /* volatile declaration */ cvattr |= BVOLATILE; /* set volatile bit */ continue; case LONG: case SHORT: if( adj != INT ) goto bad; adj = t->in.type; continue; case INT: case CHAR: case FLOAT: case DOUBLE: /* 012 - dnm */ if( noun != UNDEF ) goto bad; noun = t->in.type; continue; } } /* now, construct final type */ if( noun == UNDEF ) noun = INT; /* 012 - dnm */ /* double takes const and/or volatile, nothing else */ else if( noun == DOUBLE ){ if( unsg != INT || adj != INT) goto bad; p->in.type = DOUBLE; p->in.typattr |= cvattr; return; } /* 012 - end */ else if( noun == FLOAT ){ if( unsg != INT || adj == SHORT ) goto bad; p->in.type = (adj == LONG ? DOUBLE : FLOAT); p->in.typattr |= cvattr; return; } else if( noun == CHAR && adj != INT ) goto bad; /* now, noun is INT or CHAR */ if( adj != INT ) noun = adj; if (unsg == UNSIGNED) noun += (UNSIGNED-INT); p->in.type = noun; p->in.typattr |= cvattr; return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -