⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fend.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
/*- * 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 + -