proc.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,806 行 · 第 1/3 页

C
1,806
字号
#ifndef lintstatic char	*sccsid = " @(#)proc.c	1.3	(ULTRIX)	1/15/86";#endif lint/************************************************************************ *									* *			Copyright (c) 1986 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.	* *									* ************************************************************************//**************************************************************************			Modification History**	Sid Maxwell		29-Sep-88** 002	Changed dobss to look for variable length CHARACTER variables*	defined BSS and generate an error.**	David Metsky		14-Jan-86** 001	Replaced old version with BSD 4.3 version as part of upgrade.**	Based on:	proc.c		5.3		8/29/85**************************************************************************//* * proc.c * * Routines for handling procedures, f77 compiler, pass 1. * * University of Utah CS Dept modification history: * * $Header: proc.c,v 5.2 85/08/10 05:03:34 donn Exp $ * $Log:	proc.c,v $ * Revision 5.2  85/08/10  05:03:34  donn * Support for NAMELIST i/o from Jerry Berkman. *  * Revision 5.1  85/08/10  03:49:14  donn * 4.3 alpha *  * Revision 3.11  85/06/04  03:45:29  donn * Changed retval() to recognize that a function declaration might have * bombed out earlier, leaving an error node behind... *  * Revision 3.10  85/03/08  23:13:06  donn * Finally figured out why function calls and array elements are not legal * dummy array dimension declarator elements.  Hacked safedim() to stop 'em. *  * Revision 3.9  85/02/02  00:26:10  donn * Removed the call to entrystab() in enddcl() -- this was redundant (it was * also done in startproc()) and confusing to dbx to boot. *  * Revision 3.8  85/01/14  04:21:53  donn * Added changes to implement Jerry's '-q' option. *  * Revision 3.7  85/01/11  21:10:35  donn * In conjunction with other changes to implement SAVE statements, function * nameblocks were changed to make it appear that they are 'saved' too -- * this arranges things so that function return values are forced out of * register before a return. *  * Revision 3.6  84/12/10  19:27:20  donn * comblock() signals an illegal common block name by returning a null pointer, * but incomm() wasn't able to handle it, leading to core dumps.  I put the * fix in incomm() to pick up null common blocks. *  * Revision 3.5  84/11/21  20:33:31  donn * It seems that I/O elements are treated as character strings so that their * length can be passed to the I/O routines...  Unfortunately the compiler * assumes that no temporaries can be of type CHARACTER and casually tosses * length and type info away when removing TEMP blocks.  This has been fixed... *  * Revision 3.4  84/11/05  22:19:30  donn * Fixed a silly bug in the last fix. *  * Revision 3.3  84/10/29  08:15:23  donn * Added code to check the type and shape of subscript declarations, * per Jerry Berkman's suggestion. *  * Revision 3.2  84/10/29  05:52:07  donn * Added change suggested by Jerry Berkman to report an error when an array * is redimensioned. *  * Revision 3.1  84/10/13  02:12:31  donn * Merged Jerry Berkman's version into mine. *  * Revision 2.1  84/07/19  12:04:09  donn * Changed comment headers for UofU. *  * Revision 1.6  84/07/19  11:32:15  donn * Incorporated fix to setbound() to detect backward array subscript limits. * The fix is by Bob Corbett, donated by Jerry Berkman. *  * Revision 1.5  84/07/18  18:25:50  donn * Fixed problem with doentry() where a placeholder for a return value * was not allocated if the first entry didn't require one but a later * entry did. *  * Revision 1.4  84/05/24  20:52:09  donn * Installed firewall #ifdef around the code that recycles stack temporaries, * since it seems to be broken and lacks a good fix for the time being. *  * Revision 1.3  84/04/16  09:50:46  donn * Fixed mkargtemp() so that it only passes back a copy of a temporary, keeping * the original for its own use.  This fixes a set of bugs that are caused by * elements in the argtemplist getting stomped on. *  * Revision 1.2  84/02/28  21:12:58  donn * Added Berkeley changes for subroutine call argument temporaries fix. *  */#include "defs.h"#ifdef SDB#	include <a.out.h>#	ifndef N_SO#		include <stab.h>#	endif#endifextern flag namesflag;typedef  struct SizeList    {      struct SizeList *next;      ftnint size;      struct VarList *vars;    }  sizelist;typedef  struct VarList    {      struct VarList *next;      Namep np;      struct Equivblock *ep;    }  varlist;LOCAL sizelist *varsizes;/* start a new procedure */newproc(){if(parstate != OUTSIDE)	{	execerr("missing end statement", CNULL);	endproc();	}parstate = INSIDE;procclass = CLMAIN;	/* default */}/* end of procedure. generate variables, epilogs, and prologs */endproc(){struct Labelblock *lp;if(parstate < INDATA)	enddcl();if(ctlstack >= ctls)	err("DO loop or BLOCK IF not closed");for(lp = labeltab ; lp < labtabend ; ++lp)	if(lp->stateno!=0 && lp->labdefined==NO)		errstr("missing statement number %s", convic(lp->stateno) );if (optimflag)  optimize();outiodata();epicode();procode();donmlist();dobss();#if FAMILY == PCC	putbracket();#endiffixlwm();procinit();	/* clean up for next procedure */}/* End of declaration section of procedure.  Allocate storage. */enddcl(){register struct Entrypoint *ep;parstate = INEXEC;docommon();doequiv();docomleng();for(ep = entries ; ep ; ep = ep->entnextp) {	doentry(ep);}}/* ROUTINES CALLED WHEN ENCOUNTERING ENTRY POINTS *//* Main program or Block data */startproc(prgname, class)Namep prgname;int class;{struct Extsym *progname;register struct Entrypoint *p;if(prgname)	procname = prgname->varname;if(namesflag == YES) {	fprintf(diagfile, "   %s", (class==CLMAIN ? "MAIN" : "BLOCK DATA") );	if(prgname)		fprintf(diagfile, " %s", varstr(XL, procname) );	fprintf(diagfile, ":\n");	}if( prgname ) 	progname = newentry( prgname );else	progname = NULL;p = ALLOC(Entrypoint);if(class == CLMAIN)	puthead("MAIN_", CLMAIN);else	puthead(CNULL, CLBLOCK);if(class == CLMAIN)	newentry( mkname(5, "MAIN") );p->entryname = progname;p->entrylabel = newlabel();entries = p;procclass = class;retlabel = newlabel();#ifdef SDBif(sdbflag) {         entrystab(p,class);}#endif}/* subroutine or function statement */struct Extsym *newentry(v)register Namep v;{register struct Extsym *p;p = mkext( varunder(VL, v->varname) );if(p==NULL || p->extinit || ! ONEOF(p->extstg, M(STGUNKNOWN)|M(STGEXT)) )	{	if(p == 0)		dclerr("invalid entry name", v);	else	dclerr("external name already used", v);	return(0);	}v->vstg = STGAUTO;v->vprocclass = PTHISPROC;v->vclass = CLPROC;p->extstg = STGEXT;p->extinit = YES;return(p);}entrypt(class, type, length, entname, args)int class, type;ftnint length;Namep entname;chainp args;{struct Extsym *entry;register Namep q;register struct Entrypoint *p, *ep;if(namesflag == YES) {	if(class == CLENTRY)		fprintf(diagfile, "       entry ");	if(entname)		fprintf(diagfile, "   %s", varstr(XL, entname->varname) );	fprintf(diagfile, ":\n");	}if( entname->vclass == CLPARAM ) {	errstr("entry name %s used in 'parameter' statement", 		varstr(XL, entname->varname) );	return;	}if( ((type == TYSUBR) || (class == CLENTRY && proctype == TYSUBR)) 	&& (entname->vtype != TYUNKNOWN && entname->vtype != TYSUBR) ) {	errstr("subroutine entry %s previously declared",		varstr(XL, entname->varname) );	return;	}if(  (entname->vstg != STGEXT && entname->vstg != STGUNKNOWN)	||  (entname->vdim != NULL) ) {	errstr("subroutine or function entry %s previously declared",		varstr(XL, entname->varname) );	return;	}if( (class == CLPROC || class == CLENTRY) && type != TYSUBR )	/* arrange to save function return values */	entname->vsave = YES;	entry = newentry( entname );if(class != CLENTRY)	puthead( varstr(XL, procname = entry->extname), class);q = mkname(VL, nounder(XL,entry->extname) );if( (type = lengtype(type, (int) length)) != TYCHAR)	length = 0;if(class == CLPROC)	{	procclass = CLPROC;	proctype = type;	procleng = length;	retlabel = newlabel();	if(type == TYSUBR)		ret0label = newlabel();	}p = ALLOC(Entrypoint);if(entries)	/* put new block at end of entries list */	{	for(ep = entries; ep->entnextp; ep = ep->entnextp)		;	ep->entnextp = p;	}else	entries = p;p->entryname = entry;p->arglist = args;p->entrylabel = newlabel();p->enamep = q;if(class == CLENTRY)	{	class = CLPROC;	if(proctype == TYSUBR)		type = TYSUBR;	}q->vclass = class;q->vprocclass = PTHISPROC;settype(q, type, (int) length);/* hold all initial entry points till end of declarations */if(parstate >= INDATA) {	doentry(p);}#ifdef SDB	if(sdbflag)	{ /* may need to preserve CLENTRY here */	entrystab(p,class);	}#endif}/* generate epilogs */LOCAL epicode(){register int i;if(procclass==CLPROC)	{	if(proctype==TYSUBR)		{		putlabel(ret0label);		if(substars)			putforce(TYINT, ICON(0) );		putlabel(retlabel);		goret(TYSUBR);		}	else	{		putlabel(retlabel);		if(multitype)			{			typeaddr = autovar(1, TYADDR, PNULL);			putbranch( cpexpr(typeaddr) );			for(i = 0; i < NTYPES ; ++i)				if(rtvlabel[i] != 0)					{					putlabel(rtvlabel[i]);					retval(i);					}			}		else			retval(proctype);		}	}else if(procclass != CLBLOCK)	{	putlabel(retlabel);	goret(TYSUBR);	}}/* generate code to return value of type  t */LOCAL retval(t)register int t;{register Addrp p;switch(t)	{	case TYCHAR:	case TYCOMPLEX:	case TYDCOMPLEX:		break;	case TYLOGICAL:		t = tylogical;	case TYADDR:	case TYSHORT:	case TYLONG:		p = (Addrp) cpexpr(retslot);		p->vtype = t;		putforce(t, p);		break;	case TYREAL:	case TYDREAL:		p = (Addrp) cpexpr(retslot);		p->vtype = t;		putforce(t, p);		break;	case TYERROR:		return;		/* someone else already complained */	default:		badtype("retval", t);	}goret(t);}/* Allocate extra argument array if needed. Generate prologs. */LOCAL procode(){register struct Entrypoint *p;Addrp argvec;#if TARGET==GCOS	argvec = autovar(lastargslot/SZADDR, TYADDR, PNULL);#else	if(lastargslot>0 && nentry>1)#if TARGET == VAX		argvec = autovar(1 + lastargslot/SZADDR, TYADDR, PNULL);#else		argvec = autovar(lastargslot/SZADDR, TYADDR, PNULL);#endif	else		argvec = NULL;#endif#if TARGET == PDP11	/* for the optimizer */	if(fudgelabel)		putlabel(fudgelabel);#endiffor(p = entries ; p ; p = p->entnextp)	prolog(p, argvec);#if FAMILY == PCC	putrbrack(procno);#endifprendproc();}/*   manipulate argument lists (allocate argument slot positions) * keep track of return types and labels */LOCAL doentry(ep)struct Entrypoint *ep;{register int type;register Namep np;chainp p;register Namep q;Addrp mkarg();++nentry;if(procclass == CLMAIN)	{	if (optimflag)		optbuff (SKLABEL, 0, ep->entrylabel, 0);	else		putlabel(ep->entrylabel);	return;	}else if(procclass == CLBLOCK)	return;impldcl( np = mkname(VL, nounder(XL, ep->entryname->extname) ) );type = np->vtype;if(proctype == TYUNKNOWN)	if( (proctype = type) == TYCHAR)		procleng = (np->vleng ? np->vleng->constblock.const.ci : (ftnint) (-1));if(proctype == TYCHAR)	{	if(type != TYCHAR)		err("noncharacter entry of character function");	else if( (np->vleng ? np->vleng->constblock.const.ci : (ftnint) (-1)) != procleng)		err("mismatched character entry lengths");	}else if(type == TYCHAR)	err("character entry of noncharacter function");else if(type != proctype)	multitype = YES;if(rtvlabel[type] == 0)	rtvlabel[type] = newlabel();ep->typelabel = rtvlabel[type];if(type == TYCHAR)	{	if(chslot < 0)		{		chslot = nextarg(TYADDR);		chlgslot = nextarg(TYLENG);		}	np->vstg = STGARG;	np->vardesc.varno = chslot;	if(procleng < 0)		np->vleng = (expptr) mkarg(TYLENG, chlgslot);	}else if( ISCOMPLEX(type) )	{	np->vstg = STGARG;	if(cxslot < 0)		cxslot = nextarg(TYADDR);	np->vardesc.varno = cxslot;	}else if(type != TYSUBR)	{	if(retslot == NULL)		retslot = autovar(1, TYDREAL, PNULL);	np->vstg = STGAUTO;	np->voffset = retslot->memoffset->constblock.const.ci;	}for(p = ep->arglist ; p ; p = p->nextp)	if(! (( q = (Namep) (p->datap) )->vdcldone) )		q->vardesc.varno = nextarg(TYADDR);for(p = ep->arglist ; p ; p = p->nextp)	if(! (( q = (Namep) (p->datap) )->vdcldone) )		{		impldcl(q);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?