📄 pftn.c
字号:
#ifndef lintstatic char *sccsid = "@(#)pftn.c 4.1 (ULTRIX) 11/23/87";#endif lint/************************************************************************ * * Modification History * * @(#)pftn.c 1.3 (Berkeley) 7/15/83 * * David Metsky, 2-Jul-87 * 012- Fixed up types() so it can handle DOUBLE as a type that needs * to be merged with const and volatile. * * Victoria Holt, 14-Apr-86 * 011- Bug fix for constant pointers. * * Lu Anne Van de Pas, 02-Mar-86 * 010- Added support from intializing f floating constants * * Victoria Holt, 26-Feb-86 * 009- Added support for const and volatile. * * Rich Phillips, 14-Sep-84 * 008- I put the "if" in the wrong place for fix 6. It should go at * the end of the switch, not after the default case. * * Rich Phillips, 13-Sep-84 * 007- Back out of fix 004, see mod history in local.c for reason. * * Rich Phillips, 07-Sep-84 * 006- Fix change 003 so previous symbol table entries are not removed * causing "undefined" errors in later function definitions. * * Rich Phillips, 31-Jul-84 * 005- Issue a warning if the user redeclares a function argument at * level 2. * * Rich Phillips, 20-Jul-84 * 004- Set SWASREG flag in the symbol table if a name was defined * with REGISTER, but changed by the compiler. * * Rich Phillips, 16-Jul-84 * 003- Issue an error when an arguement is defined but not in the arguement * list of the function def. It wasn't being caught when the name was used * previously for something else that is still accessable. * * Stephen Reilly, 16-Dec-83 * 002- Give errors if we no that we can not do initialization * * Stephen Reilly, 07-Dec-83 * 001- Fix problem when formal parameters are structures that * sre not aligned properly on the stack * ***********************************************************************//************************************************************************ * * * Copyright (c) 1983 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************/# include "mfile1"unsigned int offsz;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();int ddebug = 0;struct symtab * mknonuniq();defid( q, class ) NODE *q; { register struct symtab *p; int idp; TWORD type, typattr, stattr; TWORD stp; int scl; int dsym, ddef; int slev, temp; int changed; if( q == NIL ) return; /* an error was detected */ if( q < node || q >= &node[TREESZ] ) cerror( "defid call" ); idp = q->tn.rval; if( idp < 0 ) cerror( "tyreduce" ); p = &stab[idp];# ifndef BUG1 if( ddebug ){#ifndef FLEXNAMES printf( "defid( %.8s (%d), ", p->sname, idp );#else printf( "defid( %s (%d), ", p->sname, idp );#endif tprint( q->in.type ); printf( ", %s, (%d,%d) ), level %d\n", scnames(class), q->fn.cdim, q->fn.csiz, blevel ); }# endif fixtype( q, class ); type = q->in.type; typattr = q->in.typattr; class = fixclass( class, type ); stp = p->stype; slev = p->slevel; stattr = p->stypattr;# ifndef BUG1 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 ); }# endif if( stp == FTN && p->sclass == SNULL )goto enter; /* name encountered as function, not yet defined */ /* RAP003 The logic of the following "if" was changed to catch the case where we are at level 1 and the previous use of the name is not FARG or UNDEF. An external for example. */ if( blevel == 1 ){ if( stp!=FARG ) switch( class ){ default: #ifndef FLEXNAMES if(!(class&FIELD)) uerror( "declared argument %.8s is missing", p->sname );#else if(!(class&FIELD)) uerror( "declared argument %s is missing", p->sname );#endif case MOS: case STNAME: case MOU: case UNAME: case MOE: case ENAME: case TYPEDEF: if (stp!=UNDEF) goto mayhide; /*RAP006 RAP008*/ ; } goto enter; } else if ( stp == UNDEF || stp == FARG ) goto enter; mayhide: if( type != stp ) goto mismatch; if (typattr != stattr) goto mismatch; /* test (and possibly adjust) dimensions */ dsym = p->dimoff; ddef = q->fn.cdim; changed = 0; for( temp=type; temp&TMASK; temp = DECREF(temp) ){ if( ISARY(temp) ){ if (dimtab[dsym] == 0) { dimtab[dsym] = dimtab[ddef]; changed = 1; } else if (dimtab[ddef]!=0&&dimtab[dsym]!=dimtab[ddef]) { goto mismatch; } ++dsym; ++ddef; } } if (changed) { FIXDEF(p); } /* check that redeclarations are to the same structure */ if( (temp==STRTY||temp==UNIONTY||temp==ENUMTY) && p->sizoff != q->fn.csiz && class!=STNAME && class!=UNAME && class!=ENAME ){ goto mismatch; } scl = ( p->sclass );# ifndef BUG1 if( ddebug ){ printf( " previous class: %s\n", scnames(scl) ); }# endif 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: /* allow nonunique structure/union member names */ if( class==MOU || class==MOS || class & FIELD ){/* make a new entry */ int * memp; p->sflags |= SNONUNIQ; /* old entry is nonunique */ /* determine if name has occurred in this structure/union */ for( memp = ¶mstk[paramno-1]; /* while */ *memp>=0 && stab[*memp].sclass != STNAME && stab[*memp].sclass != UNAME; /* iterate */ --memp){ char * cname, * oname; if( stab[*memp].sflags & SNONUNIQ ){int k; cname=p->sname; oname=stab[*memp].sname;#ifndef FLEXNAMES for(k=1; k<=NCHNAM; ++k){ if(*cname++ != *oname)goto diff; if(!*oname++)break; }#else if (cname != oname) goto diff;#endif uerror("redeclaration of: %s",p->sname); break; diff: continue; } } p = mknonuniq( &idp ); /* update p and idp to new entry */ goto enter; } if( blevel > slev && class != EXTERN && class != FORTRAN && class != UFORTRAN && !( class == LABEL && slev >= 2 ) ){ /*RAP005 Issue a warning if a function paramater has just been redeclared first thing in the function. sub(a) int a; { int a; } */ if (slev==1 && blevel==2)#ifndef FLEXNAMES werror("immediate redeclaration of argument: %.8s", p->sname);#else werror("immediate redeclaration of argument: %s", p->sname);#endif q->tn.rval = idp = hide( p ); p = &stab[idp]; goto enter; }#ifndef FLEXNAMES uerror( "redeclaration of %.8s", p->sname );#else uerror( "redeclaration of %s", p->sname );#endif if( class==EXTDEF && ISFTN(type) ) curftn = idp; return; enter: /* make a new entry */# ifndef BUG1 if( ddebug ) printf( " new entry made\n" );# endif if( type == UNDEF ) uerror("void type for %s",p->sname); p->stype = type; p->stypattr = typattr; 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 */ dstash( idp ); } else { switch( BTYPE(type) ){ case STRTY: case UNIONTY: case ENUMTY: p->sizoff = q->fn.csiz; break; default: p->sizoff = BTYPE(type); } } /* copy dimensions */ p->dimoff = q->fn.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);# ifndef BUG1 if( ddebug ) printf( " dimoff, sizoff, offset: %d, %d, %d\n", p->dimoff, p->sizoff, p->offset );# endif }psave( i ){ if( paramno >= PARAMSZ ){ cerror( "parameter stack overflow"); } paramstk[ paramno++ ] = i; }ftnend(){ /* end of function */ if( retlab != NOLAB ){ /* inside a real function */ efcode(); } checkst(0); retstat = 0; tcheck(); curclass = SNULL; brklab = contlab = retlab = NOLAB; flostat = 0; if( nerrors == 0 ){ if( psavbc != & asavbc[0] ) cerror("bcsave error"); if( paramno != 0 ) cerror("parameter reset error"); if( swx != 0 ) cerror( "switch error"); } psavbc = &asavbc[0]; paramno = 0; autooff = AUTOINIT; minrvar = regvar = MAXRVAR; reached = 1; swx = 0; swp = swtab; locctr(DATA); }dclargs(){ register i, j; register struct symtab *p; register NODE *q; argoff = ARGINIT;# ifndef BUG1 if( ddebug > 2) printf("dclargs()\n");# endif for( i=0; i<paramno; ++i ){ if( (j = paramstk[i]) < 0 ) continue; p = &stab[j];# ifndef BUG1 if( ddebug > 2 ){ printf("\t%s (%d) ",p->sname, j); tprint(p->stype); printf("\n"); }# endif if( p->stype == FARG ) { q = block(FREE,NIL,NIL,INT,0,INT); q->tn.rval = j; q->in.typattr = p->stypattr; defid( q, PARAM ); } FIXARG(p); /* local arg hook, eg. for sym. debugger */ oalloc( p, &argoff ); /* always set aside space, even for register arguments */ if( p->stype==STRTY || p->stype==UNIONTY )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -