📄 fend.c
字号:
/*- * Copyright (c) 1980, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char sccsid[] = "@(#)fend.c 8.1 (Berkeley) 6/6/93";#endif /* not lint */#include "whoami.h"#include "0.h"#include "tree.h"#include "opcode.h"#include "objfmt.h"#include "align.h"#include "tmps.h"/* * this array keeps the pxp counters associated with * functions and procedures, so that they can be output * when their bodies are encountered */int bodycnts[ DSPLYSZ ];#ifdef PC# include "pc.h"# include <pcc.h>#endif PC#ifdef OBJint cntpatch;int nfppatch;#endif OBJ#include "tree_ty.h"struct nl *Fp;int pnumcnt;/* * Funcend is called to * finish a block by generating * the code for the statements. * It then looks for unresolved declarations * of labels, procedures and functions, * and cleans up the name list. * For the program, it checks the * semantics of the program * statement (yuchh). */funcend(fp, bundle, endline) struct nl *fp; struct tnode *bundle; int endline;{ register struct nl *p; register int i, b; int inp, out; struct tnode *blk; bool chkref; struct nl *iop; char *cp; extern int cntstat;# ifdef PC struct entry_exit_cookie eecookie;# endif PC# ifndef PC int var;# endif PC cntstat = 0;/* * yyoutline(); */ if (program != NIL) line = program->value[3]; blk = bundle->stmnt_blck.stmnt_list; if (fp == NIL) { cbn--;# ifdef PTREE nesting--;# endif PTREE return; }#ifdef OBJ /* * Patch the branch to the entry point of the function. * Assure alignment of O_BEG structure. */ if (((int)lc & 02) == 0) word(0); patch4((PTR_DCL) fp->value[NL_ENTLOC]); /* * Put out the block entrance code and the block name. * HDRSZE is the number of bytes of info in the static * BEG data area exclusive of the proc name. It is * currently defined as: /* struct hdr { /* long framesze; /* number of bytes of local vars */ /* long nargs; /* number of bytes of arguments */ /* bool tests; /* TRUE => perform runtime tests */ /* short offset; /* offset of procedure in source file */ /* char name[1]; /* name of active procedure */ /* }; */# define HDRSZE (2 * sizeof(long) + sizeof(short) + sizeof(bool)) var = put(2, ((lenstr(fp->symbol,0) + HDRSZE) << 8) | (cbn == 1 && opt('p') == 0 ? O_NODUMP: O_BEG), (long)0); /* * output the number of bytes of arguments * this is only checked on formal calls. */ (void) put(2, O_CASE4, cbn == 1 ? (long)0 : (long)(fp->value[NL_OFFS]-DPOFF2)); /* * Output the runtime test mode for the routine */ (void) put(2, sizeof(bool) == 2 ? O_CASE2 : O_CASE4, opt('t') ? TRUE : FALSE); /* * Output line number and routine name */ (void) put(2, O_CASE2, bundle->stmnt_blck.line_no); putstr(fp->symbol, 0);#endif OBJ#ifdef PC /* * put out the procedure entry code */ eecookie.nlp = fp; if ( fp -> class == PROG ) { /* * If there is a label declaration in the main routine * then there may be a non-local goto to it that does * not appear in this module. We have to assume that * such a reference may occur and generate code to * prepare for it. */ if ( parts[ cbn ] & LPRT ) { parts[ cbn ] |= ( NONLOCALVAR | NONLOCALGOTO ); } codeformain(); ftnno = fp -> value[NL_ENTLOC]; prog_prologue(&eecookie); stabline(bundle->stmnt_blck.line_no); stabfunc(fp, "program", bundle->stmnt_blck.line_no , (long) 0 ); } else { ftnno = fp -> value[NL_ENTLOC]; fp_prologue(&eecookie); stabline(bundle->stmnt_blck.line_no); stabfunc(fp, fp->symbol, bundle->stmnt_blck.line_no, (long)(cbn - 1)); for ( p = fp -> chain ; p != NIL ; p = p -> chain ) { stabparam( p , p -> value[ NL_OFFS ] , (int) lwidth(p->type)); } if ( fp -> class == FUNC ) { /* * stab the function variable */ p = fp -> ptr[ NL_FVAR ]; stablvar( p , p -> value[ NL_OFFS ] , (int) lwidth( p -> type)); } /* * stab local variables * rummage down hash chain links. */ for ( i = 0 ; i <= 077 ; i++ ) { for ( p = disptab[ i ] ; p != NIL ; p = p->nl_next) { if ( ( p -> nl_block & 037 ) != cbn ) { break; } /* * stab locals (not parameters) */ if ( p -> symbol != NIL ) { if ( p -> class == VAR && p -> value[ NL_OFFS ] < 0 ) { stablvar( p , p -> value[ NL_OFFS ] , (int) lwidth( p -> type ) ); } else if ( p -> class == CONST ) { stabconst( p ); } } } } } stablbrac( cbn ); /* * ask second pass to allocate known locals */ putlbracket(ftnno, &sizes[cbn]); fp_entrycode(&eecookie);#endif PC if ( monflg ) { if ( fp -> value[ NL_CNTR ] != 0 ) { inccnt( fp -> value [ NL_CNTR ] ); } inccnt( bodycnts[ fp -> nl_block & 037 ] ); } if (fp->class == PROG) { /* * The glorious buffers option. * 0 = don't buffer output * 1 = line buffer output * 2 = 512 byte buffer output */# ifdef OBJ if (opt('b') != 1) (void) put(1, O_BUFF | opt('b') << 8);# endif OBJ# ifdef PC if ( opt( 'b' ) != 1 ) { putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) , "_BUFF" ); putleaf( PCC_ICON , opt( 'b' ) , 0 , PCCT_INT , (char *) 0 ); putop( PCC_CALL , PCCT_INT ); putdot( filename , line ); }# endif PC inp = 0; out = 0; for (p = fp->chain; p != NIL; p = p->chain) { if (pstrcmp(p->symbol, input->symbol) == 0) { inp++; continue; } if (pstrcmp(p->symbol, output->symbol) == 0) { out++; continue; } iop = lookup1(p->symbol); if (iop == NIL || bn != cbn) { error("File %s listed in program statement but not declared", p->symbol); continue; } if (iop->class != VAR) { error("File %s listed in program statement but declared as a %s", p->symbol, classes[iop->class]); continue; } if (iop->type == NIL) continue; if (iop->type->class != FILET) { error("File %s listed in program statement but defined as %s", p->symbol, nameof(iop->type)); continue; }# ifdef OBJ (void) put(2, O_CON24, text(iop->type) ? 0 : width(iop->type->type)); i = lenstr(p->symbol,0); (void) put(2, O_CON24, i); (void) put(2, O_LVCON, i); putstr(p->symbol, 0); (void) put(2, O_LV | bn<<8+INDX, (int)iop->value[NL_OFFS]); (void) put(1, O_DEFNAME);# endif OBJ# ifdef PC putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) , "_DEFNAME" ); putLV( p -> symbol , bn , iop -> value[NL_OFFS] , iop -> extra_flags , p2type( iop ) ); putCONG( p -> symbol , strlen( p -> symbol ) , LREQ ); putop( PCC_CM , PCCT_INT ); putleaf( PCC_ICON , strlen( p -> symbol ) , 0 , PCCT_INT , (char *) 0 ); putop( PCC_CM , PCCT_INT ); putleaf( PCC_ICON , text(iop->type) ? 0 : width(iop->type->type) , 0 , PCCT_INT , (char *) 0 ); putop( PCC_CM , PCCT_INT ); putop( PCC_CALL , PCCT_INT ); putdot( filename , line );# endif PC } } /* * Process the prog/proc/func body */ noreach = FALSE; line = bundle->stmnt_blck.line_no; statlist(blk);# ifdef PTREE { pPointer Body = tCopy( blk ); pDEF( PorFHeader[ nesting -- ] ).PorFBody = Body; }# endif PTREE# ifdef OBJ if (cbn== 1 && monflg != FALSE) { patchfil((PTR_DCL) (cntpatch - 2), (long)cnts, 2); patchfil((PTR_DCL) (nfppatch - 2), (long)pfcnt, 2); }# endif OBJ# ifdef PC if ( fp -> class == PROG && monflg ) { putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) , "_PMFLUSH" ); putleaf( PCC_ICON , cnts , 0 , PCCT_INT , (char *) 0 ); putleaf( PCC_ICON , pfcnt , 0 , PCCT_INT , (char *) 0 ); putop( PCC_CM , PCCT_INT ); putLV( PCPCOUNT , 0 , 0 , NGLOBAL , PCCT_INT ); putop( PCC_CM , PCCT_INT ); putop( PCC_CALL , PCCT_INT ); putdot( filename , line ); }# endif PC /* * Clean up the symbol table displays and check for unresolves */ line = endline; if (fp->class == PROG && inp == 0 && (input->nl_flags & (NUSED|NMOD)) != 0) { recovered(); error("Input is used but not defined in the program statement"); } if (fp->class == PROG && out == 0 && (output->nl_flags & (NUSED|NMOD)) != 0) { recovered(); error("Output is used but not defined in the program statement"); } b = cbn; Fp = fp; chkref = (syneflg == errcnt[cbn] && opt('w') == 0)?TRUE:FALSE; for (i = 0; i <= 077; i++) { for (p = disptab[i]; p != NIL && (p->nl_block & 037) == b; p = p->nl_next) { /* * Check for variables defined * but not referenced */ if (chkref && p->symbol != NIL) switch (p->class) { case FIELD: /* * If the corresponding record is * unused, we shouldn't complain about * the fields. */ default: if ((p->nl_flags & (NUSED|NMOD)) == 0) { warning(); nerror("%s %s is neither used nor set", classes[p->class], p->symbol); break; } /* * If a var parameter is either * modified or used that is enough. */ if (p->class == REF) continue;# ifdef OBJ if ((p->nl_flags & NUSED) == 0) { warning(); nerror("%s %s is never used", classes[p->class], p->symbol); break; }# endif OBJ# ifdef PC if (((p->nl_flags & NUSED) == 0) && ((p->extra_flags & NEXTERN) == 0)) { warning(); nerror("%s %s is never used", classes[p->class], p->symbol);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -