home *** CD-ROM | disk | FTP | other *** search
- #
- /*
- * C compiler, phase 1
- *
- *
- * Handles processing of declarations,
- * except for top-level processing of
- * externals.
- */
-
- #include "c0h.c"
-
- /*
- * Process a sequence of declaration statements
- */
- declist(sclass)
- {
- register sc, elsize, offset;
- int type;
-
- offset = 0;
- sc = sclass;
- while ((elsize = getkeywords(&sclass, &type)) != -1) {
- offset = declare(sclass, type, offset, elsize);
- sclass = sc;
- }
- return(offset+align(INT, offset, 0));
- }
-
- /*
- * Read the keywords introducing a declaration statement
- */
- getkeywords(scptr, tptr)
- int *scptr, *tptr;
- {
- register skw, tkw, longf;
- int o, elsize, isadecl, ismos;
-
- isadecl = 0;
- longf = 0;
- tkw = -1;
- skw = *scptr;
- elsize = 0;
- ismos = skw==MOS;
- for (;;) {
- mosflg = ismos;
- switch ((o=symbol())==KEYW? cval: -1) {
-
- case AUTO:
- case STATIC:
- case EXTERN:
- case REG:
- if (skw && skw!=cval)
- error("Conflict in storage class");
- skw = cval;
- break;
-
- case LONG:
- longf++;
- break;
-
- case STRUCT:
- o = STRUCT;
- elsize = strdec(&o, ismos);
- cval = o;
- case INT:
- case CHAR:
- case FLOAT:
- case DOUBLE:
- if (tkw>=0)
- error("Type clash");
- tkw = cval;
- break;
-
- default:
- peeksym = o;
- if (isadecl==0)
- return(-1);
- if (tkw<0)
- tkw = INT;
- if (skw==0)
- skw = AUTO;
- if (longf) {
- if (tkw==FLOAT)
- tkw = DOUBLE;
- else if (tkw==INT)
- tkw = LONG;
- else
- error("Misplaced 'long'");
- }
- *scptr = skw;
- *tptr = tkw;
- return(elsize);
- }
- isadecl++;
- }
- }
-
- /*
- * Process a structure declaration; a subroutine
- * of getkeywords.
- */
- strdec(tkwp, mosf)
- int *tkwp;
- {
- register elsize, o;
- register struct hshtab *ssym;
- int savebits;
- struct hshtab *ds;
-
- mosflg = 1;
- ssym = 0;
- if ((o=symbol())==NAME) {
- ssym = csym;
- if (ssym->hclass==0) {
- ssym->hclass = STRTAG;
- ssym->lenp = dimp;
- chkdim();
- dimtab[dimp++] = 0;
- }
- if (ssym->hclass != STRTAG)
- redec();
- mosflg = mosf;
- o = symbol();
- }
- mosflg = 0;
- if (o != LBRACE) {
- if (ssym==0) {
- syntax:
- decsyn(o);
- return(0);
- }
- if (ssym->hclass!=STRTAG)
- error("Bad structure name");
- if ((elsize = dimtab[ssym->lenp&0377])==0) {
- *tkwp = RSTRUCT;
- elsize = ssym;
- }
- peeksym = o;
- } else {
- ds = defsym;
- mosflg = 0;
- savebits = bitoffs;
- bitoffs = 0;
- elsize = declist(MOS);
- bitoffs = savebits;
- defsym = ds;
- if ((o = symbol()) != RBRACE)
- goto syntax;
- if (ssym) {
- if (dimtab[ssym->lenp&0377])
- error("%.8s redeclared", ssym->name);
- dimtab[ssym->lenp&0377] = elsize;
- }
- }
- return(elsize);
- }
-
- /*
- * Check that the dimension table has not overflowed
- */
- chkdim()
- {
- if (dimp >= dimsiz) {
- error("Dimension/struct table overflow");
- exit(1);
- }
- }
-
- /*
- * Process a comma-separated list of declarators
- */
- declare(askw, tkw, offset, elsize)
- {
- register int o;
- register int skw;
-
- skw = askw;
- do {
- offset =+ decl1(skw, tkw, offset, elsize);
- } while ((o=symbol()) == COMMA);
- if (o==SEMI || o==RPARN && skw==ARG1)
- return(offset);
- decsyn(o);
- }
-
- /*
- * Process a single declarator
- */
- decl1(askw, tkw, offset, elsize)
- {
- int t1, chkoff, a;
- register int type, skw;
- register struct hshtab *dsym;
-
- skw = askw;
- chkoff = 0;
- mosflg = skw==MOS;
- if ((peeksym=symbol())==SEMI || peeksym==RPARN)
- return(0);
- /*
- * Filler field
- */
- if (peeksym==COLON && skw==MOS) {
- peeksym = -1;
- t1 = conexp();
- elsize = align(tkw, offset, t1);
- bitoffs =+ t1;
- return(elsize);
- }
- if ((t1=getype()) < 0)
- goto syntax;
- type = 0;
- do
- type = type<<TYLEN | (t1 & XTYPE);
- while (((t1=>>TYLEN) & XTYPE)!=0);
- type =| tkw;
- dsym = defsym;
- if (!(dsym->hclass==0
- || (skw==ARG && dsym->hclass==ARG1)
- || (skw==EXTERN && dsym->hclass==EXTERN && dsym->htype==type)))
- if (skw==MOS && dsym->hclass==MOS && dsym->htype==type)
- chkoff = 1;
- else {
- redec();
- goto syntax;
- }
- dsym->htype = type;
- if (skw)
- dsym->hclass = skw;
- if (skw==ARG1) {
- if (paraml==0)
- paraml = dsym;
- else
- parame->hoffset = dsym;
- parame = dsym;
- }
- if (elsize && ((type&TYPE)==RSTRUCT || (type&TYPE)==STRUCT)) {
- dsym->lenp = dimp;
- chkdim();
- dimtab[dimp++] = elsize;
- }
- elsize = 0;
- if (skw==MOS) {
- elsize = length(dsym);
- t1 = 0;
- if ((peeksym = symbol())==COLON) {
- elsize = 0;
- peeksym = -1;
- t1 = conexp();
- dsym->hflag =| FFIELD;
- }
- a = align(type, offset, t1);
- elsize =+ a;
- offset =+ a;
- if (t1) {
- if (chkoff && (dsym->bitoffs!=bitoffs
- || dsym->flen!=t1))
- redec();
- dsym->bitoffs = bitoffs;
- dsym->flen = t1;
- bitoffs =+ t1;
- }
- if (chkoff && dsym->hoffset != offset)
- redec();
- dsym->hoffset = offset;
- }
- if ((dsym->htype&XTYPE)==FUNC) {
- if (dsym->hclass!=EXTERN && dsym->hclass!=AUTO)
- error("Bad function");
- dsym->hclass = EXTERN;
- }
- if (dsym->hclass==AUTO) {
- autolen =+ rlength(dsym);
- dsym->hoffset = -autolen;
- } else if (dsym->hclass==STATIC) {
- dsym->hoffset = isn;
- outcode("BBNBNB", BSS, LABEL, isn++,
- SSPACE, rlength(dsym), PROG);
- } else if (dsym->hclass==REG) {
- if ((type&TYPE)>CHAR && (type&XTYPE)==0
- || (type&XTYPE)>PTR || regvar<3)
- error("Bad register %o", type);
- dsym->hoffset = --regvar;
- }
- syntax:
- return(elsize);
- }
-
- /*
- * Read a declarator and get the implied type
- */
- getype()
- {
- register int o, type;
- register struct hshtab *ds;
-
- switch(o=symbol()) {
-
- case TIMES:
- return(getype()<<TYLEN | PTR);
-
- case LPARN:
- type = getype();
- if ((o=symbol()) != RPARN)
- goto syntax;
- goto getf;
-
- case NAME:
- defsym = ds = csym;
- type = 0;
- ds->ssp = dimp;
- getf:
- switch(o=symbol()) {
-
- case LPARN:
- if (xdflg) {
- xdflg = 0;
- ds = defsym;
- declare(ARG1, 0, 0, 0);
- defsym = ds;
- xdflg++;
- } else
- if ((o=symbol()) != RPARN)
- goto syntax;
- type = type<<TYLEN | FUNC;
- goto getf;
-
- case LBRACK:
- chkdim();
- if ((o=symbol()) != RBRACK) {
- peeksym = o;
- cval = conexp();
- for (o=ds->ssp&0377; o<dimp; o++)
- dimtab[o] =* cval;
- dimtab[dimp++] = cval;
- if ((o=symbol())!=RBRACK)
- goto syntax;
- } else
- dimtab[dimp++] = 1;
- type = type<<TYLEN | ARRAY;
- goto getf;
- }
- peeksym = o;
- return(type);
- }
- syntax:
- decsyn(o);
- return(-1);
- }
-
- /*
- * Enforce alignment restrictions in structures,
- * including bit-field considerations.
- */
- align(type, offset, aflen)
- {
- register a, t, flen;
- char *ftl;
-
- flen = aflen;
- a = offset;
- t = type;
- ftl = "Field too long";
- if (flen==0 && bitoffs) {
- a =+ (bitoffs-1) / NBPC;
- bitoffs = 0;
- }
- while ((t&XTYPE)==ARRAY)
- t = decref(t);
- if (t!=CHAR) {
- a = (a+ALIGN) & ~ALIGN;
- if (a>offset)
- bitoffs = 0;
- }
- if (flen) {
- if (type==INT) {
- if (flen > NBPW)
- error(ftl);
- if (flen+bitoffs > NBPW) {
- bitoffs = 0;
- a =+ NCPW;
- }
- } else if (type==CHAR) {
- if (flen > NBPC)
- error(ftl);
- if (flen+bitoffs > NCPW) {
- bitoffs = 0;
- a =+ 1;
- }
- } else
- error("Bad type for field");
- }
- return(a-offset);
- }
-
- /*
- * Complain about syntax error in declaration
- */
- decsyn(o)
- {
- error("Declaration syntax");
- errflush(o);
- }
-
- /*
- * Complain about a redeclaration
- */
- redec()
- {
- error("%.8s redeclared", defsym->name);
- }
-