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

📄 dcl2.c

📁 c 语言编译器 源代码- c compiler
💻 C
📖 第 1 页 / 共 3 页
字号:
/* @(#) dcl2.c 1.5 1/27/86 17:48:40 */ /*ident	"@(#)cfront:src/dcl2.c	1.5" *//**************************************************************************	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.dcl2.c:*************************************************************************/#include "cfront.h"#include "size.h"Pname classdef.has_ictor()/*	does this class have a constructor taking no arguments?*/{	Pname c = has_ctor();	Pfct f;	Plist l;	if (c == 0) return 0;	f = (Pfct)c->tp;	switch (f->base) {	default:		error('i',"%s: bad constructor (%k)",string,c->tp->base);	case FCT:		switch (f->nargs) {		case 0:		return c;		default:	if (f->argtype->n_initializer) return c;		}		return 0;	case OVERLOAD:		for (l=Pgen(f)->fct_list; l; l=l->l) {			Pname n = l->f;			f = (Pfct)n->tp;			switch (f->nargs) {			case 0:		return n;			default:	if (f->argtype->n_initializer) return n;			}		}		return 0;	}}gen.gen(char* s){	char * p = new char[ strlen(s)+1 ];	base = OVERLOAD;	strcpy(p,s);	string = p;	fct_list = 0;}Pname gen.add(Pname n,int sig)/*	add "n" to the tail of "fct_list"	(overloaded names are searched in declaration order)	detect:	 	multiple identical declarations			declaration after use			multiple definitions*/{	Pfct f = (Pfct)n->tp;	Pname nx;	if (f->base != FCT) error(0,"%n: overloaded non-F",n);	if ( fct_list && (nx=find(f)) ) {//error('d',"add old %n",nx);/*		Pfct nf = (Pfct)nx->tp;		if (nf->body) {			if (f->body)				error("two definitions for overloaded%n",n);		}		else {			if (f->body) nf->body = f->body;		}*/		Nold = 1;	}	else {		char* s = string;//error('d',"add new %s",s);		if (fct_list || sig || n->n_oper) {			char buf[128];			char* bb = n->tp->signature(buf);			int l1 = strlen(s);			int l2 = bb-buf-1;			char* p = new char[l1+l2+1];			strcpy(p,s);			strcpy(p+l1,buf);			n->string = p;		}		else 			n->string = s;		nx = new name;		*nx = *n;		PERM(nx);		Nold = 0;		if (fct_list) {			Plist gl;			for (gl=fct_list; gl->l; gl=gl->l) ;			gl->l = new name_list(nx,0); 		}		else			fct_list = new name_list(nx,0);		nx->n_list = 0;	}	return nx;}Pname gen.find(Pfct f){	Plist gl;		for (gl=fct_list; gl; gl=gl->l) {		Pname nx = gl->f;		Pfct fx = (Pfct)nx->tp;		Pname a, ax;		int vp = 0;//error('d',"find %s",nx->string);		if (fx->nargs_known != f->nargs_known) {			if (fx->nargs && fx->nargs_known!=ELLIPSIS) continue;		}		for (ax=fx->argtype, a=f->argtype; a&&ax; ax=ax->n_list, a=a->n_list) {//error('d',"ax %d %d a %d %d",ax->tp,ax->tp->base,a->tp,a->tp->base);			Ptype at = ax->tp;			if ( at->check(a->tp,0)) goto xx;			if ( vrp_equiv ) vp = 1;			switch (at->base) {			case CHAR:			case SHORT:			case INT:			case LONG:				if (Pbase(at)->b_unsigned ^ Pbase(a->tp)->b_unsigned) error('w',"the overloading mechanism cannot tell an unsigned%k from a%k",at->base,at->base);			}		}		if (ax) {			if (ax->n_initializer)				error("Ir makes overloaded %s() ambiguous",string);			continue;		}		if (a) {			if (a->n_initializer)				error("Ir makes overloaded %s() ambiguous",string);			continue;		}		if ( fx->returns->check(f->returns,0) )			error("two different return valueTs for overloaded %s: %t and %t", string, fx->returns, f->returns);		if (vp) error('w',"ATs differ (only): [] vs *");		return nx;	xx:;	}	return 0;}void classdef.dcl(Pname cname, Ptable tbl){	int nmem;	Pname p;	Pptr cct;	Pbase bt;	Pname px;	Ptable btbl;	int bvirt;	Pclass bcl;	int i;	int fct_seen = 0;	int static_seen = 0;	int local = tbl!=gtbl;	int byte_old = byte_offset;	int bit_old = bit_offset;	int max_old = max_align;	int boff;	int in_union;	int usz;	int make_ctor = 0;	int make_dtor = 0;	/* this is the place for paranoia */	if (this == 0) error('i',"0->Cdef.dcl(%d)",tbl);	if (base != CLASS) error('i',"Cdef.dcl(%d)",base);	if (cname == 0) error('i',"unNdC");	if (cname->tp != this) error('i',"badCdef");	if (tbl == 0) error('i',"Cdef.dcl(%n,0)",cname);	if (tbl->base != TABLE) error('i',"Cdef.dcl(%n,tbl=%d)",cname,tbl->base);	nmem = pubmem->no_of_names() + privmem->no_of_names() + pubdef->no_of_names();	in_union = (csu==UNION || csu==ANON);	if (clbase) {		if (clbase->base != TNAME) error("BC%nU",clbase);		clbase = Pbase(clbase->tp)->b_name;		bcl = (Pclass)clbase->tp;		if ((bcl->defined&SIMPLIFIED) == 0) error("BC%nU",clbase);		tbl = bcl->memtbl;		if (tbl->base != TABLE) error('i',"badBC table %d",tbl);		btbl = tbl;		bvirt = bcl->virt_count;		if (bcl->csu == UNION) error('s',"C derived from union");		if (in_union) 			error("derived union");		else			if (pubbase == 0) csu = CLASS;		boff = bcl->real_size;		max_align = bcl->align();		bit_ass = bcl->bit_ass;	}	else {		btbl = 0;		bvirt = 0;		boff = 0;		if (!in_union) csu = (virt_count) ? CLASS : STRUCT;		while (tbl!=gtbl && tbl->t_name) tbl = tbl->next; // nested classes		max_align = AL_STRUCT;		bit_ass = 1;	// can be bitwise copied	}	memtbl->set_scope(tbl);	memtbl->set_name(cname);	if (nmem) memtbl->grow((nmem<=2)?3:nmem);	cc->stack();	cc->not = cname;	cc->cot = this;//error('d',"classdef%n",cname);	byte_offset = usz = boff;	bit_offset = 0;	bt = new basetype(COBJ,cname);	bt->b_table = memtbl;	this_type = cc->tot = cct = new ptr(PTR,bt,0);	PERM(cct);	PERM(bt);	for (p=privmem; p; p=px) {		Pname m;		px = p->n_list;//error('d',"privmem%n %d",p,p->tp->base);		if (p->tp->base==FCT) {			Pfct f = (Pfct)p->tp;			Pblock b = f->body;			f->body = 0;			switch( p->n_sto ) {			case AUTO:			case STATIC:			case REGISTER:			case EXTERN:				error("M%n cannot be%k",p,p->n_sto);				p->n_sto = 0;			}			m =  p->dcl(memtbl,0);			if (b) {				if (m->tp->defined&(DEFINED|SIMPLIFIED))					error("two definitions of%n",m);				else if (p->where.line!=m->where.line)					error('s',"previously declared%n cannot be defined inCD",p);				else					Pfct(m->tp)->body = b;			}			fct_seen = 1;		}		else {			m = p->dcl(memtbl,0);			if (m) {				if (m->n_stclass==STATIC) {					static_seen = 1;					m->n_sto = (tbl == gtbl) ? 0 : STATIC;					if (m->n_initializer) error('s',"staticM%n withIr",m);				}				if (in_union) {					if (usz < byte_offset) usz = byte_offset;					byte_offset = 0;				}			}		}	}	if (privmem && csu==STRUCT) csu = CLASS;	for (p=pubmem; p; p=px) {		Pname m;		px = p->n_list;//error('d',"pubmem%n %d",p,p->tp->base);		if (p->tp->base == FCT) {			Pfct f = (Pfct)p->tp;			Pblock b = f->body;			f->body = 0;			switch(p->n_sto) {			case AUTO:			case STATIC:			case REGISTER:			case EXTERN:				error("M%n cannot be%k",p,p->n_sto);				p->n_sto = 0;			}			m = p->dcl(memtbl,PUBLIC);			if (b) {				if (m->tp->defined&(DEFINED|SIMPLIFIED))					error("two definitions of%n",m);				else if (p->where.line!=m->where.line)					error('s',"previously declared%n cannot be defined inCD",p);				else					Pfct(m->tp)->body = b;			}			fct_seen = 1;		}		else {			m = p->dcl(memtbl,PUBLIC);			if (m) {				if (m->n_stclass==STATIC) {					m->n_sto = (tbl == gtbl) ? 0 : STATIC;					static_seen = 1;					if (m->n_initializer) error('s',"staticM%n withIr",m);				}				if (in_union) {					if (usz < byte_offset) usz = byte_offset;					byte_offset = 0;				}			}		}		/*delete p;*/	}/*	pubmem = 0;*///	if (local && fct_seen) error("FM of local%k %s",csu,string);	if (in_union) byte_offset = usz;	if (virt_count || bvirt) {	/* assign virtual indices */		Pname vp[100];		Pname nn;		nn = has_ctor();		if (nn==0 || nn->n_table!=memtbl) make_ctor = 1;		{	//	FUDGE vtbl			char* s = new char[20];			sprintf(s,"%s__vtbl",string);			Pname n = new name(s);			n->tp = Pfctvec_type;			Pname nn = gtbl->insert(n,0);			nn->use();		}		if (virt_count = bvirt)			for (i=0; i<bvirt; i++) vp[i] = bcl->virt_init[i];for ( nn=memtbl->get_mem(i=1); nn; nn=memtbl->get_mem(++i) ) {	switch (nn->tp->base) {	case FCT:	{	Pfct f = (Pfct)nn->tp;		if (bvirt) {			Pname vn = btbl->look(nn->string,0);			if (vn) {	/* match up with base class */				if (vn->n_table==gtbl) goto vvv;				Pfct vnf;				switch (vn->tp->base) {				case FCT:					vnf = (Pfct)vn->tp;					if (vnf->f_virtual) {						if (vnf->check(f,0)) error("virtual%nT mismatch:%t and%t",nn,f,vnf);						f->f_virtual = vnf->f_virtual;						vp[f->f_virtual-1] = nn;					}					else						goto vvv;					break;				case OVERLOAD:				{	Pgen g = (Pgen)vn->tp;					if (f->f_virtual					|| Pfct(g->fct_list->f->tp)->f_virtual)						error('s',"virtual%n overloaded inBC but not in derivedC",nn);					break;				}				default:					goto vvv;				}			}			else				goto vvv;		}		else {		vvv:/*error('d',"vvv: %n f_virtual %d virt_count %d",nn,f->f_virtual,virt_count);*/			if (f->f_virtual)  {				f->f_virtual = ++virt_count;				switch (f->f_virtual) {				case 1:				{	Pname vpn = new name("_vptr");					vpn->tp = Pfctvec_type;					(void) vpn->dcl(memtbl,PUBLIC);					delete vpn;				}				default:					vp[f->f_virtual-1] = nn;				}			}		}		break;	}	case OVERLOAD:	{	Plist gl;		Pgen g = (Pgen)nn->tp;/*error('d',"overload%n bvirt==%d",nn,bvirt);*/		if (bvirt) {			Pname vn = btbl->look(nn->string,0);			Pgen g2;			Pfct f2;			if (vn) {/*error('d',"vn%n tp%k",vn,vn->tp->base);*/				if (vn->n_table == gtbl) goto ovvv;				switch (vn->tp->base) {				default:					goto ovvv;				case FCT:					f2 = (Pfct)vn->tp;					if (f2->f_virtual					|| Pfct(g->fct_list->f->tp)->f_virtual)						error('s',"virtual%n overloaded in derivedC but not inBC",nn);					break;				case OVERLOAD:					g2 = (Pgen)vn->tp;											for (gl=g->fct_list; gl; gl=gl->l) {						Pname fn = gl->f;						Pfct f = (Pfct)fn->tp;						Pname vn2 = g2->find(f);						if (vn2 == 0) {							if (f->f_virtual) error('s',"virtual overloaded%n not found inBC",fn);						}						else {							Pfct vn2f = (Pfct)vn2->tp;							if (vn2f->f_virtual) {								f->f_virtual = vn2f->f_virtual;								vp[f->f_virtual-1] = fn;							}						}					}					break;				}			}			else				goto ovvv;		}		else {		ovvv:			for (gl=g->fct_list; gl; gl=gl->l) {				Pname fn = gl->f;				Pfct f = (Pfct)fn->tp;/*fprintf(stderr,"fn %s f %d %d %d count %d\n",fn->string,f,f->base,f->f_virtual,virt_count+1);*/				if (f->f_virtual) {					f->f_virtual = ++virt_count;					switch (f->f_virtual) {					case 1:					{	Pname vpn = new name("_vptr");						vpn->tp = Pfctvec_type;						(void) vpn->dcl(memtbl,0);						delete vpn;					}					default:						vp[f->f_virtual-1] = fn;					}				}			}		}		break;	}}		}		virt_init = new Pname[virt_count];		for (i=0; i<virt_count; i++) virt_init[i] = vp[i];	}	Pname pnx;	for (p=pubdef; p; p=pnx) {		char* qs = p->n_qualifier->string;		char* ms = p->string;		Pname cx;		Ptable ctbl;		Pname mx;		pnx = p->n_list;//error('d',"dcl: pubdef %s::%s",qs,ms);		if (strcmp(ms,qs)==0) ms = "_ctor";		for (cx = clbase; cx; cx = Pclass(cx->tp)->clbase) {			if (strcmp(cx->string,qs) == 0) goto ok;		}		error("publicQr %s not aBC",qs);		continue;	ok:		ctbl = Pclass(cx->tp)->memtbl;		mx = ctbl->lookc(ms,0);//error('d',"ms %d %d %d",mx,Ebase,Epriv);		if (Ebase) {	// cc->nof ??			if (!Ebase->has_friend(cc->nof)) error("QdMN%n is in privateBC",p);		}		else if (Epriv) {			if (!Epriv->has_friend(cc->nof)) error("QdMN%n is private",p);		}		if (mx == 0) {			error("C%n does not have aM %s",cx,p->string);			p->tp = any_type;		}		else {			if (mx->tp->base==OVERLOAD) error('s',"public specification of overloaded%n",mx);			p->base = PUBLIC;		}				p->n_qualifier = mx;		(void) memtbl->insert(p,0);//error('d',"bbb");		if (Nold) error("twoDs of CM%n",p);	}	pubdef = 0;	if (bit_offset) byte_offset += (bit_offset/BI_IN_BYTE+1);	real_size = byte_offset;//error('d',"%s: rz=%d (bits %d)",string,byte_offset,bit_offset);	if (byte_offset < SZ_STRUCT) byte_offset = SZ_STRUCT;	int waste = byte_offset%max_align;	if (waste) byte_offset += max_align-waste;//error('d',"%s: sz=%d al=%d",string,byte_offset,max_align);	obj_size = byte_offset;	obj_align = max_align;		if ( has_dtor() && has_ctor()==0)		error('w',"%s has destructor but no constructor",string);	{	// now look look at the members	Pname m;	Pclass oc = in_class;	int ct = has_ctor()==0;	int dt = has_dtor()==0;	int un = csu==UNION;	Pname statc = 0;	Pname statd = 0;	for (m=memtbl->get_mem(i=1); m; m=memtbl->get_mem(++i) ) {		if (m->base == PUBLIC) continue;		Ptype t = m->tp;		switch (t->base) {		default:			if (ct && make_ctor==0) {				if (t->is_ref()) error("reference%n inC %s without constructor",m,string);				if (t->tconst() && vec_const==0) error("constant%n inC %s without constructor",m,string);			}			break;		case FCT:		case OVERLOAD:		case CLASS:		case ENUM:			continue;		case VEC:			break;		}		Pname cn = t->is_cl_obj();		if (cn == 0) cn = cl_obj_vec;		if (cn) {			Pclass cl = (Pclass)cn->tp;			if (cl->bit_ass == 0) bit_ass = 0;	// no bit copy			if (ct || dt || un) {

⌨️ 快捷键说明

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