コード例 #1
0
ファイル: typ.C プロジェクト: seyko2/cfront-3
void type::dcl(Ptable tbl)
/*
	go through the type (list) and
	(1) evaluate vector dimensions
	(2) evaluate field sizes
	(3) lookup struct tags, etc.
	(4) handle implicit tag declarations
*/
{
	Ptype t = this;

	// processing_sizeof suppresses errors for refs to names in the arg 
	// to sizeof.  Turn errors back on for exprs within type specs
	// (such as array subscripts)
	int os = processing_sizeof;
	processing_sizeof = 0;

	if (this == 0)
		error('i',"T::dcl(this==0)");
	if (tbl->base != TABLE)
		error('i',"T::dcl(%d)",tbl->base);

xx:
	switch (t->base) {
	case TYPE:
		t = Pbase(t)->b_name->tp;
		goto xx;
	case PTR:
	case RPTR:
	{
		Pptr p = Pptr(t);
		if(p->memof == 0 && p->ptname) { // T::*, where T is a template formal
			Ptype tp = p->ptname->tp->skiptypedefs();
			switch (tp->base) {
			    case COBJ:
				{
				p->memof = tp->classtype();
				if (p->typ)
				{
					Ptype t = p->typ->skiptypedefs();
					if (t && t->base==FCT)
					{
						Pfct(t)->memof = p->memof;
					}
				}
				break;
				}
			    case CLASS:
				{
				p->memof = Pclass(tp);
				Ptype t = p->typ->skiptypedefs();
				Pfct f = Pfct(t); // safe???
				f->memof = p->memof;
				break;
				}	
			    default:
				error("illegalZizedP toM %t::*",tp);
				break;
			}
		}
		t = p->typ;
		if (t->base == TYPE) {
			Ptype tt = Pbase(t)->b_name->tp;
			if (tt->base == FCT)
				p->typ = tt;
			goto done;
		}
		goto xx;
	}

	case VEC:
	{
		Pvec v = Pvec(t);
		Pexpr e = v->dim;
		if (e) {
			Ptype et;
			v->dim = e = e->typ(tbl);
			if (e->tp->skiptypedefs()->base == COBJ) {
				e = check_cond(e,DEREF,tbl);
				v->dim = e;
			}
			et = e->tp;
			if (et->integral(0) == 'A') {
				error("UN in array dimension");
			}
			else {
				long long i;
				Neval = 0;
				i = e->eval();
				if (Neval == 0) {
					if (largest_int<i)
						error("array dimension too large");
					v->size = int(i);

					DEL(v->dim);
					v->dim = 0;
				}

				if (new_type) {
					if (Neval)
						;
					else if (i == 0)
						v->dim = zero;
					else if (i < 0) {
						error("negative array dimension");
						i = 1;
					}
				}
				else {
					if (Neval)
						error("%s",Neval);
					else if (i == 0) {
						error("array dimension == 0");
						v->dim=e;
					}
					else if (i < 0) {
						error("negative array dimension");
						i = 1;
					}
				}
			}
		}
		t = v->typ;
	llx:
		switch (t->base) {
		case TYPE:
			t = Pbase(t)->b_name->tp;
			goto llx;
		case FCT:
			v->typ = t;
			break;
		case VEC:				
			if (Pvec(t)->dim==0 && Pvec(t)->size==0)
				error("null dimension (something like [][] seen)");
		}
		goto xx;
	}

	case FCT:
	{
		Pfct f = Pfct(t);
		void dargs(Pname, Pfct, Ptable);

		if (f->argtype)
			dargs(0,f,tbl);
		for (Pname n=f->argtype; n; n = n->n_list) {
			Ptype t = n->tp;
			n->tp->dcl(tbl);
			while(t->base==TYPE)
				t = Pbase(t)->b_name->tp;
			if(t->base==VEC)
				n->tp = new ptr(PTR,Pvec(t)->typ);
		}
		Pname cn = f->returns->is_cl_obj();
		if (cn && Pclass(cn->tp)->has_itor())
			make_res(f);
		else if (f->f_this == 0)
			f->f_args = f->argtype;

		t = f->returns;
		goto xx;
	}

	case FIELD:
	{
		Pbase f = Pbase(t);
		Pexpr e = Pexpr(f->b_name);
		long long i;
		Ptype et;
		e = e->typ(tbl);
		f->b_name = Pname(e);
		et = e->tp;
		if (et->integral(0) == 'A') {
			error("UN in field size");
			i = 1;
		}
		else {
			Neval = 0;
			i = e->eval();
			if (Neval)
				error("%s",Neval);
			else if (i < 0) {
				error("negative field size");
				i = 1;
			}
			else if (f->b_fieldtype->tsizeof()*BI_IN_BYTE < i)
				error("field size > sizeof(%t)",f->b_fieldtype);
			DEL(e);
		}
		f->b_bits = int(i);
		f->b_name = 0;
		break;
	}
	}
done:
	processing_sizeof = os;
	return;
}
コード例 #2
0
ファイル: norm.c プロジェクト: setekhid/cfront1
void fct.argdcl(Pname dcl, Pname fn)
/*
	sort out the argument types for old syntax:
			f(a,b) int a; char b; { ... }
	beware of
			f(a) struct s { int a; }; struct s a;
*/
{
	Pname n;
/*fprintf(stderr,"%d argtype %d %d dcl %d %d\n",this, argtype, argtype?argtype->base:0, dcl, dcl?dcl->base:0); fflush(stderr);*/
	switch (base) {
	case FCT:	break;
	case ANY:	return;
	default:	error('i',"argdcl(%d)",base);
	}

	if (argtype) {
		switch (argtype->base) {
		case NAME:
			if (dcl) error("badF definition syntax");
			for (n=argtype; n; n=n->n_list) {
				if (n->string == 0) n->string = make_name('A');
			}
			return;
		case ELIST:	// expression list:	f(a,b,c) int a; ... { ... }
				// scan the elist and build a NAME list
		{	Pexpr e;
			Pname nn;
			Pname tail = 0;
			n = 0;
			if (old_fct_accepted == 0) error('w',&fn->where,"old style definition of%n",fn);
			for (e=Pexpr(argtype); e; e=e->e2) {
				Pexpr id = e->e1;
				if (id->base != NAME) {
					error("NX inAL");
					argtype = 0;
					dcl = 0;
					break;
				}
				nn = new name(id->string);
				if (n)
					tail = tail->n_list = nn;
				else
					tail = n = nn;
			}
			argtype = n;
			break;
		}
		default:
			error("ALX(%d)",argtype->base);
			argtype = 0;
			dcl = 0;
		}
	}
	else {
		nargs_known = !fct_void;
		nargs = 0;
		if (dcl) error("ADL forF withoutAs");
		return;
	}

	nargs_known = 0;

	if (dcl) {
		Pname d;
		Pname dx;
		/*	for each  argument name see if its type is specified
			in the declaration list otherwise give it the default type
		*/

		for (n=argtype; n; n=n->n_list) {
			char* s = n->string;
			if (s == 0) {
				error("AN missing inF definition");
				n->string = s = make_name('A');
			}
			else if (n->tp) error("twoTs forA %s",n->string);

			for (d=dcl; d; d=d->n_list) {
				if (strcmp(s,d->string) == 0) {
					if (d->tp->base == VOID) {
						error("voidA%n",d);
						d->tp = any_type;
					}
					n->tp = d->tp;
					n->n_sto = d->n_sto;
					d->tp = 0;	/* now merged into argtype */
					goto xx;
				}
			}
			n->tp = defa_type;
		xx:;
			if (n->tp == 0) error('i',"noT for %s",n->string);
		}
	
		/*	now scan the declaration list for "unused declarations"
			and delete it
		*/
		for (d=dcl; d; d=dx) {
			dx = d->n_list;
			if (d->tp) {	/* not merged with argtype list */
				/*if (d->base == TNAME)  ??? */
				switch (d->tp->base) {
				case CLASS:
				case ENUM:
					/* WARNING: this will reverse the order of
					   class and enum declarations
					*/
					d->n_list = argtype;
					argtype = d;
					break;
				default:
					 error("%n inADL not inAL",d);
				}
			}
		}
	}

	/* add default argument types if necessary */
	for (n=argtype; n; n=n->n_list) {
		if (n->tp == 0) n->tp = defa_type;
		nargs++;
	}
}