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

📄 dcl.c

📁 CFront1.0的源代码,第一代C++编译器的思想...
💻 C
📖 第 1 页 / 共 4 页
字号:
/* @(#) dcl.c 1.6 1/27/86 17:48:35 */ /*ident	"@(#)cfront:src/dcl.c	1.6" *//**************************************************************************	C++ source for cfront, the C++ compiler front-end	written in the computer science research center of Bell Labs	Copyright (c) 1984 AT&T, Inc. All Rights Reserved	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T, INC.	dcl.c:	``declare'' all names, that is insert them in the appropriate symbol tables.	Calculate the size for all objects (incl. stack frames),	and find store the offsets for all members (incl. auto variables).	"size.h" holds the constants needed for calculating sizes.	Note that (due to errors) functions may nest*****************************************************************************/#include "cfront.h"#include "size.h"class dcl_context ccvec[MAXCONT], * cc = ccvec;int byte_offset;int bit_offset;int max_align;int stack_size;int enum_count;int friend_in_class = 0;void name.check_oper(Pname cn)/*	check declarations of operators, ctors, dtors*/{	switch (n_oper) {	case CALL:		if (cn == 0) error("operator() must be aM");		break;	case DEREF:		if (cn == 0) error("operator[] must be aM");		break;	case 0:	case TNAME:	/* may be a constructor */		if (cn && strcmp(cn->string,string)==0) {			if (tp->base == FCT) {				Pfct f = (Pfct)tp;				if (f->returns!=defa_type && fct_void==0)					error("%s::%s() with returnT",string,string);				f->returns = void_type;				string = "_ctor";				n_oper = CTOR;			}			else				error('s',"struct%cnM%n",cn,cn);		}		else			n_oper = 0;		break;	case DTOR:	/* must be a destructor */		if (cn == 0) {			n_oper = 0;			error("destructor ~%s() not inC",string);		}		else if (strcmp(cn->string,string) == 0) {			Pfct f = (Pfct)tp;			string = "_dtor";			if (tp->base != FCT) {				error("%s::~%s notF",cn->string,cn->string);				tp = new fct(void_type,0,1);			}			else if (f->returns!=defa_type && fct_void==0)				error("%s::~%s() with returnT",cn->string,cn->string);			if (f->argtype) {				if (fct_void==0) error("%s::~%s() withAs",cn->string,cn->string);				f->nargs = 0;				f->nargs_known = 1;				f->argtype = 0;			}			f->returns = void_type;		}		else {			error("~%s in %s",string,cn->string);			n_oper = 0;		}		break;	case TYPE:		if (cn == 0) {			error("operator%t() not aM",(Ptype)n_initializer);			n_oper = 0;			n_initializer = 0;		} else {			Pfct f = (Pfct)tp;			Ptype tx = (Ptype)n_initializer;/*error('d',"operator%t()",tx);*/			n_initializer = 0;			if (f->base != FCT) error("badT for%n::operator%t()",cn,tx);			if (f->returns != defa_type) {				if (f->returns->check(tx,0)) error("bad resultT for%n::operator%t()",cn,tx);				DEL(f->returns);			}			if (f->argtype) {				error("%n::operator%t() withAs",cn,tx);				f->argtype = 0;			}			f->returns = tx;			Pname nx = tx->is_cl_obj();			if (nx && can_coerce(tx,cn->tp)) error("both %n::%n(%n) and %n::operator%t()",cn,cn,nx,tx);			char buf[128];			char* bb = tx->signature(buf);			int l2 = bb-buf-1;			char* p = new char[l2+3];			p[0] = '_';			p[1] = 'O';			strcpy(p+2,buf);			string = p;		}		break;	}}Pname name.dcl(Ptable tbl, TOK scope)/*	enter a copy of this name into symbol table "tbl";		- create local symbol tables as needed		"scope" gives the scope in which the declaration was found		- EXTERN, FCT, ARG, PUBLIC, or 0	Compare "scope" with the specified storage class "n_sto"		- AUTO, STATIC, REGISTER, EXTERN, OVERLOAD, FRIEND, or 0	After name.dcl()	n_stclass ==	0		class or enum member			REGISTER	auto variables declared register			AUTO		auto variables not registers			STATIC		statically allocated object	n_scope ==	0		private class member			PUBLIC		public class member			EXTERN		name valid in this and other files			STATIC		name valid for this file only			FCT		name local to a function			ARG		name of a function argument			ARGT		name of a type defined in an					argument list	typecheck function bodies;	typecheck initializers;	note that functions (error recovery) and classes (legal) nest	The return value is used to chain symbol table entries, but cannot	be used for printout because it denotes the sum of all type information	for the name	names of typenames are marked with n_oper==TNAME	WARNING: The handling of scope and storage class is cursed!*/{	Pname nn;	Ptype nnt = 0;	Pname odcl = Cdcl;	if (this == 0) error('i',"0->name.dcl()");	if (tbl == 0) error('i',"%n->name.dcl(tbl=0,%k)",this,scope);	if (tbl->base != TABLE) error('i',"%n->name.dcl(tbl=%d,%k)",this,tbl->base,scope);	if (tp == 0) error('i',"name.dcl(%n,%k)T missing",this,scope);/*fprintf(stderr,"(%d %s)->dcl(tbl=%d,scope=%d) tp = (%d %d)\n",this,string,tbl,scope,tp,tp->base); fflush(stderr);*/	Cdcl = this;	switch (base) {	case TNAME:		tp->dcl(tbl);		PERM(tp);		nn = new name(string);		nn->base = TNAME;		nn->tp = tp;		tbl->insert(nn,0);		delete nn;		Cdcl = odcl;		return this;	case NAME:		switch (n_oper) {		case TNAME:			if (tp->base != FCT) n_oper = 0;			break;		case COMPL:			if (tp->base != FCT) {				error("~%s notF",string);				n_oper = 0;			}			break;		}		break;	default:		error('i',"NX in name.dcl()");	}	if (n_qualifier) {	/*	class function: c::f(); */		if (tp->base != FCT) {			error("QdN%n inD of nonF",this);			Cdcl = odcl;			return 0;		}		Pname cn = n_qualifier;		switch (cn->base) {		case TNAME:			break;		case NAME:			cn = gtbl->look(cn->string,0);			if (cn && cn->base==TNAME) break;		default:			error("badQr%n for%n",n_qualifier,this);			Cdcl = odcl;			return 0;		}		cn = Pbase(cn->tp)->b_name;		if (n_oper) check_oper(cn);		Pclass cl = (Pclass)cn->tp;		if (cl == cc->cot) {			n_qualifier = 0;			goto xdr;		}		else if ((cl->defined&(DEFINED|SIMPLIFIED)) == 0) {			error("C%nU",cn);			Cdcl = odcl;			return 0;		}		Ptable etbl = cl->memtbl;		Pname x = etbl->look(string,0);		if(x==0 || x->n_table!=etbl) {			error("%n is not aM of%n",this,cn);			Cdcl = odcl;			return 0;		}	}xdr:	if (n_oper && tp->base!=FCT && n_sto!=OVERLOAD)		error("operator%k not aF",n_oper);	/*	if a storage class was specified			check that it is legal in the scope 		else			provide default storage class		some details must be left until the type of the object is known	*/	n_stclass = n_sto;	n_scope = scope;	/* default scope & storage class */	switch (n_sto) {	default:		error('i',"unX %k",n_sto);	case FRIEND:	{		Pclass cl = cc->cot;		switch (scope) {		case 0:		case PUBLIC:			break;		default:			error("friend%n not in classD(%k)",this,scope);			base = 0;			Cdcl = odcl;			return 0;		}		switch (n_oper) {		case 0:		case NEW:		case DELETE:		case CTOR:		case DTOR:		case TYPE:			n_sto = 0;			break;		default:			n_sto = OVERLOAD;		}		switch (tp->base) {	/*	case INT:	 undefined: implicitly define as class			nn = tname(CLASS);			nn->tp->dcl(gtbl);			break;	*/		case COBJ:			nn = Pbase(tp)->b_name;			break;		case CLASS:			nn = this;			break;		case FCT:			cc->stack();			cc->not = 0;			cc->tot = 0;			cc->cot = 0;			friend_in_class++;			n_sto = EXTERN;			nn = dcl(gtbl,EXTERN);			friend_in_class--;/*fprintf(stderr,"ff %s %d\n",nn->string,nn->tp->base);*/			cc->unstack();			if (nn->tp->base == OVERLOAD) {				Pgen g = (Pgen)nn->tp;				nn = g->find( (Pfct)tp );			}			break;		default:			error("badT%t of friend%n",tp,this);		}		PERM(nn);		cl->friend_list = new name_list(nn,cl->friend_list);		Cdcl = odcl;		return nn;	}	case OVERLOAD:		n_sto = 0;		switch (scope) {		case 0:		case PUBLIC:			error('w',"overload inCD (ignored)");			switch (tp->base) {			case INT:				base = 0;				Cdcl = odcl;				return this;			case FCT:				return dcl(tbl,scope);			}		}		if (n_oper && tp->base==FCT) break;		nn = tbl->insert(this,0);		if (Nold) {			if (nn->tp->base != OVERLOAD) {				error("%n redefined as overloaded",this);				nn->tp = new gen(string);			}		}		else {			nn->tp = new gen(string);		}		switch (tp->base) {		case INT:			base = 0;			Cdcl = odcl;			return nn;		case FCT:			break;		default:			error("N%n ofT%k cannot be overloaded",this,tp->base);			Cdcl = odcl;			return nn;		}		break;	case REGISTER:		if (tp->base == FCT) {			error('w',"%n: register (ignored)",this);			goto ddd;		}	case AUTO:		switch (scope) {		case 0:		case PUBLIC:		case EXTERN:			error("%k not inF",n_sto);			goto ddd;		}		break;	case EXTERN:		switch (scope) {		case ARG:			error("externA");			goto ddd;		case 0:		case PUBLIC:			/* extern is provided as a default for functions without body */			if (tp->base != FCT) error("externM%n",this);			goto ddd;		}		n_stclass = STATIC;		n_scope = EXTERN;	/* avoid FCT scoped externs to allow better checking */		break;	case STATIC:		switch (scope) {		case ARG:			error("static used forA%n",this);			goto ddd;		case 0:		case PUBLIC:			n_stclass = STATIC;			n_scope = scope;			break;		default:			n_scope = STATIC;		}		break;	case 0:	ddd:		switch (scope) {	/* default storage classes */		case EXTERN:			n_scope = EXTERN;			n_stclass = STATIC;			break;		case FCT:			if (tp->base == FCT) {				n_stclass = STATIC;				n_scope = EXTERN;			}			else				n_stclass = AUTO;			break;		case ARG:			n_stclass = AUTO;			break;		case 0:		case PUBLIC:			n_stclass = 0;			break;		}	}		/*		now insert the name into the appropriate symbol table,		and compare types with previous declarations of that name		do type dependent adjustments of the scope	*/	switch (tp->base) {	case ASM:	{	Pbase b = (Pbase)tp;		Pname n = tbl->insert(this,0);		n->assign();		n->use();		return this;	}	case CLASS:	{	Pclass cl;		Pbase bt;		Pname bn;	//	Pclass nest;		Pname nx = ktbl->look(string,0);		// TNAME//error('d',"%s: nx%n",string,nx);		if (nx == 0) {			/*	search for hidden name for					(1) nested class declaration					(2) local class declaration			*/			int tn = 0;			for (nx=ktbl->look(string,HIDDEN); nx; nx=nx->n_tbl_list) {//error('d',"%s: nxi%n key%d base%d",string,nx,nx->n_key,nx->tp->base);				if (nx->n_key != HIDDEN) continue;				if (nx->tp->base != COBJ) {					tn = 1;					continue;				}				bt = (Pbase)nx->tp;				bn = bt->b_name;				cl = (Pclass)bn->tp;				if (cl == 0) continue;			//	if ((nest=cl->in_class) && nest==cc->cot) 			//		goto bbb;			//	else			//	 if (cc->nof	/* fudge */			//		&& cc->nof->where.line<nx->where.line)					goto bbb;			}			if (tn)				error("%n redefined using typedef");			else				error('i',"%n is not aCN",this);		}		else {			if (tbl != gtbl) { // careful: local class def//error('d',"%n: local lex level %d",nx->lex_level);				if (nx->lex_level == 0) // imperfect					error('s',"localC%n and globalC%n",this,nx);			}			bt = (Pbase)nx->tp;			// COBJ			bn = bt->b_name;	//		nest = 0;

⌨️ 快捷键说明

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