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; }
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++; } }