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

📄 trees.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
#ifndef lintstatic char *sccsid = "@(#)trees.c	4.3	ULTRIX	2/4/91";#endif lint/************************************************************************ *									* *			Copyright (c) 1985 - 1989 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 * * * 018	Jon Reeves, 10-May-1989 *	Signal handler now returns void. * * 017	Jon Reeves, 03-May-1989 for Sid Maxwell *	Clean up handling of void * in : expressions. * * 016	Jon Reeves, 11-Apr-1988 *	Add ifndef econvert/endif so lint builds cleanly. * * 015	David L Ballenger, 22-Mar-1987 *	Fix problem with SUN fixes added in 010 that caused the following: *		if ((unsigned)char_variable <= 127) *	to generate a signed comparison and branch rather than unsigned. * * 014  Lu Anne Van de Pas, 14-Aug-86 *	Fixed bug with asgop; ie.  if (int < (int= float * double / float)). *	The intermediate results of the compuations are used again for the  *	comparsion so we can't optimize it.       * * 013  Victoria Holt, 14-Apr-86 *	Bug fix for constant pointers. * * 012	Lu Anne Van de Pas, 1-April-86 * 	Added floating point exception handler from 4.3, to report  *	floating point overflow and underflow faults when folding constants *	together.  * *	David L Ballenger, 18-Mar-1986 * 011	Add fix for casts of enumeration variables which was broken by *	the SUN fixes. * *	David L Ballenger, 16-Mar-1986 * 010	Add bug fixes from SUN for NFS code. * * 	Lu Anne Van de Pas, 02-Mar-86 * 009  Added support for single precision arithmetic to be done in  *	singleprec if fflag is set * *	Victoria Holt, 26-Feb-86 * 008	Added support for const and volatile. * *	David L Ballenger, 28-May-1985 * 007	Fix bug that prevented assignments between variables defined as *	void (*)(), i.e. pointer to function returning void. * *	Rich Phillips, 13-Sept-84 * 006- Back out of 003, see local.c for reason (in mod history) * *	Rich Phillips, 21-Aug-84 * 005- Issue an error when functions that do not return a value are *	used in a value required context. * *	Rich Phillips, 01-Aug-84 * 004- Issue an error if a structure or union type was specified in a *	condition, like "if (a)" where "a" is a union or structure. * *	Rich Phillips, 20-July-84 * 003-	Issue an error if unary & operator applies to a unary * with  *	NWASREG set. * *	Stephen Reilly, 13-Feb-84 * 002- Fix a coding bug from ( 001 ).  The problem was I thought asgop *	only was true for assign type operations.  Not true the RETURN *	CAST are considered assign typea which causes conversion problems. * *	Stephen Reilly, 20-Jan-84 * 001- Fix the problem with ( int op= real ). The bug was that the *	real was converted to the int rather than the int being  *	converted to real.   * ***********************************************************************/# include "mfile1"# include <setjmp.h>	    /* corrections when in violation of lint *//*	some special actions, used in finding the type of nodes */# define NCVT 01# define PUN 02# define TYPL 04# define TYPR 010# define TYMATCH 040# define LVAL 0100# define CVTO 0200# define CVTL 0400# define CVTR 01000# define PTMATCH 02000# define OTHER 04000# define NCVTR 010000/* node conventions:	NAME:	rval>0 is stab index for external		rval<0 is -inlabel number		lval is offset in bits	ICON:	lval has the value		rval has the STAB index, or - label number,			if a name whose address is in the constant		rval = NONAME means no name	REG:	rval is reg. identification cookie	*/int bdebug = 0;extern ddebug;extern fflag; 	/*vdp009*/ extern int adebug; extern int eprint();#ifndef BUG1/* vdp009 - adebug flag. Print out actions or conversions that * need to be done to the tree */ printact(t, acts)		NODE *t;	int acts;{	static struct actions {		int	a_bit;		char	*a_name;	} actions[] = {		{ PUN,		"PUN" },		{ CVTL,		"CVTL" },		{ CVTR,		"CVTR" },		{ TYPL,		"TYPL" },		{ TYPR,		"TYPR" },		{ TYMATCH,	"TYMATCH" },		{ PTMATCH,	"PTMATCH" },		{ LVAL,		"LVAL" },		{ CVTO,		"CVTO" },		{ NCVT,		"NCVT" },		{ OTHER,	"OTHER" },		{ NCVTR,	"NCVTR" },		{ 0 }	};	register struct actions *p;	char *sep = " ";	printf("actions");	for (p = actions; p->a_name; p++)		if (p->a_bit & acts) {			printf("%s%s", sep, p->a_name);			sep = "|";		}	if (!bdebug) {		printf(" for:\n");		fwalk(t, eprint, 0);	} else		putchar('\n');}#endifNODE *buildtree( o, l, r ) register NODE *l, *r; {	register NODE *p, *q;	register actions;	register opty;	register struct symtab *sp;	register NODE *lr, *ll;	int i;# ifndef BUG1	if( bdebug ) printf( "buildtree( %s, %o, %o )\n", opst[o], l, r );# endif	opty = optype(o);	/* check for constants */	if( opty == UTYPE && l->in.op == ICON ){		switch( o ){		case NOT:			if( hflag ) werror( "constant argument to NOT" );		case UNARY MINUS:		case COMPL:			if( conval( l, o, l ) ) return(l);			break;			}		}				/* lvdp009 check for both Floating constant and double	 * constant; combine unary minus node and constant node	 */ 	else if( o==UNARY MINUS && l->in.op==FCON ){		l->fpn.fval = -l->fpn.fval;		return(l);		}	else if( o==UNARY MINUS && l->in.op==DCON ){		l->dpn.dval = -l->dpn.dval;		return(l);		}	/* lvdp009 end */ 	else if( o==QUEST && l->in.op==ICON ) {		l->in.op = FREE;		r->in.op = FREE;		if( l->tn.lval ){			tfree( r->in.right );			return( r->in.left );			}		else {			tfree( r->in.left );			return( r->in.right );			}		}	else if( (o==ANDAND || o==OROR) && (l->in.op==ICON||r->in.op==ICON) ) goto ccwarn;	else if( opty == BITYPE && l->in.op == ICON && r->in.op == ICON ){		switch( o ){		case ULT:		case UGT:		case ULE:		case UGE:		case LT:		case GT:		case LE:		case GE:		case EQ:		case NE:		case ANDAND:		case OROR:		case CBRANCH:		ccwarn:			if( hflag ) werror( "constant in conditional context" );		case PLUS:		case MINUS:		case MUL:		case DIV:		case MOD:		case AND:		case OR:		case ER:		case LS:		case RS:			if( conval( l, o, r ) ) {				r->in.op = FREE;				return(l);				}			break;			}		}		/*vdp009 add test for double constant*/ 	else if( opty == BITYPE && 		(l->in.op==FCON || l->in.op==DCON || l->in.op==ICON) &&		(r->in.op==FCON || r->in.op==DCON || r->in.op==ICON) ){						if (o == PLUS || o == MINUS || o == MUL || o == DIV) {				/* vdp012 set up to handle floating 				 * point exception 				 */				extern int fpe_count;				extern jmp_buf gotfpe;								fpe_count = 0;				if (setjmp(gotfpe))					goto treatfpe;									if( l->in.op == ICON )					l->dpn.dval = l->tn.lval;				else if (l->in.op == FCON ) 	/*vdp009 */ 					l->dpn.dval = l->fpn.fval; 							if( r->in.op == ICON )					r->dpn.dval = r->tn.lval;				else if (r->in.op == FCON ) 	/*vdp009*/ 					r->dpn.dval = r->fpn.fval; 				switch(o){  					/*vdp009 conbine constants together*/ 				case PLUS:					l->dpn.dval += r->dpn.dval;					break;				case MINUS:					l->dpn.dval -= r->dpn.dval;					break;				case MUL:					l->dpn.dval *= r->dpn.dval;					break;				case DIV:					if( r->dpn.dval == 0 ) 						uerror( "division by 0." );					else 						l->dpn.dval /= r->dpn.dval;					break;					}			treatfpe:				if (fpe_count > 0) {					uerror("floating point exception in constant expression");					l->dpn.dval = 1.0; /* Fairly harmless */					}				fpe_count = -1;				l->in.op = DCON;				l->in.type = l->fn.csiz = DOUBLE;				r->in.op = FREE;				return (l);			}		}	if (asgop(o) && o != CAST) {	    if (ISRODATA(l->in.typattr, l->in.type)) {	        uerror("cannot assign to a const");	    } else {	    	if (ISPTR(l->in.type) && ISPTR(r->in.type) &&		    ISCONST(r->in.typattr)) {		   uerror("cannot assign const address to non-const pointer");		}	   }	}	if (o == INITASSIGN) o = ASSIGN;	/* its real; we must make a new node */	p = block( o, l, r, INT, 0, INT );	actions = opact(p);#ifndef	BUG1	if (adebug)				/*vdp009*/		printact(p, actions);#endif	if( actions&LVAL ){ /* check left descendent */		if( notlval(p->in.left) ) {			uerror( "illegal lhs of assignment operator" );			}		}	if( actions & NCVTR ){		p->in.left = pconvert( p->in.left );		}	else if( !(actions & NCVT ) ){		switch( opty ){		case BITYPE:			p->in.right = pconvert( p->in.right );		case UTYPE:			p->in.left = pconvert( p->in.left );			}		}	if( (actions&PUN) && (o!=CAST||cflag) ){		chkpun(p);		}	if( actions & (TYPL|TYPR) ){				/* make type equal to the left (TYPL) or		   make type equal to the right (TYPR) */    		q = (actions&TYPL) ? p->in.left : p->in.right;		p->in.type = q->in.type;		p->fn.cdim = q->fn.cdim;		p->fn.csiz = q->fn.csiz;		}	if( actions & CVTL ) p = convert( p, CVTL );	if( actions & CVTR ) p = convert( p, CVTR );	if( actions & TYMATCH ) p = tymatch(p);	if( actions & PTMATCH ) p = ptmatch(p);	if( actions & OTHER ){		l = p->in.left;		r = p->in.right;		switch(o){		case NAME:			sp = &stab[idname];			if( sp->stype == UNDEF ){#ifndef FLEXNAMES				uerror( "%.8s undefined", sp->sname );#else				uerror( "%s undefined", sp->sname );#endif				/* make p look reasonable */				p->in.type = p->fn.cdim = p->fn.csiz = INT;				p->in.typattr = 0;				p->tn.rval = idname;				p->tn.lval = 0;				defid( p, SNULL );				break;				}			p->in.type = sp->stype;			p->in.typattr = sp->stypattr;			p->fn.cdim = sp->dimoff;			p->fn.csiz = sp->sizoff;			p->tn.lval = 0;			p->tn.rval = idname;			/* special case: MOETY is really an ICON... */			if( p->in.type == MOETY ){				p->tn.rval = NONAME;				p->tn.lval = sp->offset;				p->fn.cdim = 0;				p->in.type = ENUMTY;				p->in.op = ICON;				}			break;		case ICON:			p->in.type = INT;			p->fn.cdim = 0;			p->fn.csiz = INT;			break;		case STRING:			p->in.op = NAME;			p->in.type = CHAR+ARY;			p->tn.lval = 0;			p->tn.rval = NOLAB;			p->fn.cdim = curdim;			p->fn.csiz = CHAR;			break;		/* vdp009 - distinguish between Floating constant and		 * double constant 		 */  		case FCON:			p->tn.lval = 0;			p->tn.rval = 0;			p->in.type = FLOAT;			p->fn.cdim = 0;			p->fn.csiz = FLOAT;			break;		case DCON:			p->tn.lval = 0;			p->tn.rval = 0;			p->in.type = DOUBLE;			p->fn.cdim = 0;			p->fn.csiz = DOUBLE;			break;		case STREF:			/* p->x turned into *(p+offset) */			/* rhs must be a name; check correctness */			i = r->tn.rval;			if( i<0 || ((sp= &stab[i])->sclass != MOS && sp->sclass != MOU && !(sp->sclass&FIELD)) ){				uerror( "member of structure or union required" );				}else			/* if this name is non-unique, find right one */			if( stab[i].sflags & SNONUNIQ &&				(l->in.type==PTR+STRTY || l->in.type == PTR+UNIONTY) &&				(l->fn.csiz +1) >= 0 ){				/* nonunique name && structure defined */				char * memnam, * tabnam;				register k;				int j;				int memi;				j=dimtab[l->fn.csiz+1];				for( ; (memi=dimtab[j]) >= 0; ++j ){					tabnam = stab[memi].sname;					memnam = stab[i].sname;# ifndef BUG1					if( ddebug>1 ){#ifndef FLEXNAMES						printf("member %.8s==%.8s?\n",#else						printf("member %s==%s?\n",#endif							memnam, tabnam);						}# endif					if( stab[memi].sflags & SNONUNIQ ){#ifndef FLEXNAMES						for( k=0; k<NCHNAM; ++k ){							if(*memnam++!=*tabnam)								goto next;							if(!*tabnam++) break;							}#else						if (memnam != tabnam)							goto next;#endif						r->tn.rval = i = memi;						break;						}					next: continue;					}				if( memi < 0 )#ifndef FLEXNAMES					uerror("illegal member use: %.8s",#else					uerror("illegal member use: %s",#endif						stab[i].sname);				}			else {				register j;				if( l->in.type != PTR+STRTY && l->in.type != PTR+UNIONTY ){					if( stab[i].sflags & SNONUNIQ ){						uerror( "nonunique name demands struct/union or struct/union pointer" );						}					else werror( "struct/union or struct/union pointer required" );					}				else if( (j=l->fn.csiz+1)<0 ) cerror( "undefined structure or union" );				else if( !chkstr( i, dimtab[j], DECREF(l->in.type) ) ){#ifndef FLEXNAMES					werror( "illegal member use: %.8s", stab[i].sname );#else					werror( "illegal member use: %s", stab[i].sname );#endif					}				}			p = stref( p );			p->in.typattr = stab[r->tn.rval].stypattr;			break;		case UNARY MUL:			if( l->in.op == UNARY AND ){				p->in.op = l->in.op = FREE;				p = l->in.left;				}			if( !ISPTR(l->in.type))uerror("illegal indirection");			p->in.type = DECREF(l->in.type); 			p->in.typattr = DECATTR(l->in.typattr);			p->fn.cdim = l->fn.cdim;			p->fn.csiz = l->fn.csiz;			break;		case UNARY AND:			switch( l->in.op ){			case UNARY MUL:				p->in.op = l->in.op = FREE;				p = l->in.left;			case NAME:				p->in.type = INCREF( l->in.type );  				p->in.typattr = INCATTR(l->in.typattr);				p->fn.cdim = l->fn.cdim;				p->fn.csiz = l->fn.csiz;				break;			case COMOP:				lr = buildtree( UNARY AND, l->in.right, NIL );				p->in.op = l->in.op = FREE;				p = buildtree( COMOP, l->in.left, lr );				break;			case QUEST:				lr = buildtree( UNARY AND, l->in.right->in.right, NIL );				ll = buildtree( UNARY AND, l->in.right->in.left, NIL );				p->in.op = l->in.op = l->in.right->in.op = FREE;				p = buildtree( QUEST, l->in.left, buildtree( COLON, ll, lr ) );				break;# ifdef ADDROREG			case OREG:				/* OREG was built in clocal()				 * for an auto or formal parameter				 * now its address is being taken				 * local code must unwind it				 * back to PLUS/MINUS REG ICON				 * according to local conventions				 */				{				extern NODE * addroreg();				p->in.op = FREE;				p = addroreg( l );				}				break;# endif			default:				uerror( "unacceptable operand of &" );				break;				}			break;		case LS:		case RS:		case ASG LS:		case ASG RS:			if(tsize(p->in.right->in.type, p->in.right->fn.cdim, p->in.right->fn.csiz) > SZINT)				p->in.right = makety(p->in.right, INT, 0, INT );			break;		case RETURN:		case ASSIGN:		case CAST:			/* structure assignment */			/* take the addresses of the two sides; then make an			/* operator using STASG and			/* the addresses of left and right */			{				register TWORD t;				register d, s;				if( l->fn.csiz != r->fn.csiz ) uerror( "assignment of different structures" );				r = buildtree( UNARY AND, r, NIL );				t = r->in.type;				d = r->fn.cdim;				s = r->fn.csiz;

⌨️ 快捷键说明

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