Add tests, fixes for tests, reinstate and type-convert stuff marked "bitrot"
[ccom.git] / c03.c
1 /*
2  * C compiler, phase 1
3  * Handles processing of declarations,
4  * except for top-level processing of
5  * externals.
6  */
7
8 #include <stdlib.h>
9 #include <string.h>
10 #include "c0.h"
11
12 /*
13  * Process a sequence of declaration statements
14  */
15 int declist(sclass) int sclass; {
16         register int sc, offset;
17  /*     struct nmlist typer;*/
18  struct type *dtype;
19  static struct type t_int = {INT};
20
21         offset = 0;
22         sc = sclass;
23         while (/*getkeywords(&sclass, &typer)*/(dtype = getkeywords(&sclass)) != NULL) {
24                 offset = declare(sclass, /*&typer*/dtype, offset);
25                 sclass = sc;
26         }
27         return(offset+align(/*INT*/&t_int, offset, 0));
28 }
29
30 /*
31  * Read the keywords introducing a declaration statement
32  * Store back the storage class, and fill in the type
33  * entry, which looks like a hash table entry.
34  */
35 /*int*/struct type *getkeywords(scptr/*, tptr*/) int *scptr; /*struct nmlist *tptr;*/ {
36         register int skw, tkw, longf;
37         int o, isadecl, ismos, unsignf;
38  struct type *dtype;
39  static struct type basic_types[] = {
40   {INT},
41   {CHAR},
42   {FLOAT},
43   {DOUBLE},
44   {STRUCT},
45   {RSTRUCT},
46   {LONG},
47   {UNSIGN},
48   {UNCHAR},
49   {UNLONG},
50   {VOID}
51  };
52
53         isadecl = 0;
54         longf = 0;
55         unsignf = 0;
56  /*     tptr->nl_type = INT;
57         tptr->nl_strp = NULL;
58         tptr->nl_subsp = NULL;*/
59         tkw = -1;
60         skw = *scptr;
61         ismos = skw==MOS||skw==MOU? FMOS: 0;
62  dtype = NULL;
63         for (;;) {
64                 mosflg = isadecl? ismos: 0;
65                 o = symbol();
66                 if (o==NAME && csym->nl_class==TYPEDEF) {
67                         if (tkw >= 0)
68                                 error0("type clash");
69  /*                     tkw = csym->nl_type;
70                         tptr->nl_subsp = csym->nl_subsp;
71                         tptr->nl_strp = csym->nl_strp;*/
72  dtype = csym->nl_dtype;
73                         isadecl++;
74                         continue;
75                 }
76                 switch (o==KEYW? cval: -1) {
77                 case AUTO:
78                 case STATIC:
79                 case EXTERN:
80                 case REG:
81                 case TYPEDEF:
82                         if (skw && skw!=cval) {
83                                 if (skw==ARG && cval==REG)
84                                         cval = AREG;
85                                 else
86                                         error0("Conflict in storage class");
87                         }
88                         skw = cval;
89                         break;
90
91                 case UNSIGN:
92                         unsignf++;
93                         break;
94
95                 case LONG:
96                         longf++;
97                         break;
98
99                 case ENUM:
100  /* note: this code accepts silly declarations like "enum a int b;" */
101  /* it also accepts modifiers if placed later like "enum a long b;" */
102  /* eventually we should modify this to be more like the struct case */
103                         if (longf || unsignf)
104                                 error0("Perverse modifier on 'enum'");
105                         strdec(ismos, cval);
106                         cval = INT;
107                         goto types;
108
109                 case UNION:
110                 case STRUCT:
111  /*                     tptr->nl_strp = strdec(ismos, cval); */
112  if (dtype)
113   error0("type clash");
114  dtype = (struct type *)strdec(ismos, cval);
115                         cval = STRUCT;
116  goto types_struct;
117                 case INT:
118                 case CHAR:
119                 case FLOAT:
120                 case DOUBLE:
121                 case VOID:
122                 types:
123  if (dtype)
124   goto type_clash;
125  types_struct:
126                         if (tkw>=0 && (tkw!=INT || cval!=INT))
127  type_clash:
128                                 error0("Type clash");
129                         tkw = cval;
130                         if (unscflg && cval==CHAR)
131                                 unsignf++;
132                         break;
133
134                 default:
135                         peeksym = o;
136                         if (isadecl==0)
137                                 return(/*0*/NULL);
138                         if (tkw<0)
139                                 tkw = INT;
140                         if (skw==0)
141                                 skw = blklev==0? DEFXTRN: AUTO;
142                         if (unsignf) {
143  if (dtype)
144   goto misplaced_unsigned;
145                                 if (tkw==INT)
146                                         tkw = UNSIGN;
147                                 else if (tkw==CHAR)
148                                         tkw = UNCHAR;
149                                 else if (tkw==LONG)
150                                         tkw = UNLONG;
151                                 else
152  misplaced_unsigned:
153                                         error0("Misplaced 'unsigned'");
154                         }
155                         if (longf) {
156  if (dtype)
157   goto misplaced_long;
158                                 if (tkw==FLOAT)
159                                         tkw = DOUBLE;
160                                 else if (tkw==INT)
161                                         tkw = LONG;
162                                 else if (tkw==UNSIGN)
163                                         tkw = UNLONG;
164                                 else
165  misplaced_long:
166                                         error0("Misplaced 'long'");
167                         }
168                         *scptr = skw;
169  /*                     tptr->nl_type = tkw;
170                         return(1);*/
171  return dtype ? dtype : basic_types + tkw;
172                 }
173                 isadecl++;
174         }
175 }
176
177 /*
178  * Process a structure, union, or enum declaration; a subroutine
179  * of getkeywords.
180  */
181 /*union str*/struct stype *strdec(mosf, kind) int mosf; int kind; {
182         register int elsize, o;
183         register struct nmlist *ssym;
184         int savebits;
185         struct nmlist **savememlist;
186         union str *savesparent;
187         int savenmems;
188  /*     union str *strp;*/
189  struct stype *stype;
190         struct nmlist *ds;
191         struct nmlist *mems[NMEMS];
192  /*     struct nmlist typer;*/
193         int tagkind;
194  static struct type t_int = {INT};
195
196         if (kind!=ENUM) {
197                 tagkind = STRTAG;
198                 mosflg = FTAG;
199                 if (kind==UNION)
200                         mosflg = FUNION;
201         } else {
202                 tagkind = ENUMTAG;
203                 mosflg = FENUM;
204         }
205         ssym = 0;
206         if ((o=symbol())==NAME) {
207                 ssym = csym;
208                 mosflg = mosf;
209                 o = symbol();
210                 if (o==LBRACE && ssym->nl_blklev<blklev)
211                         ssym = pushdecl(ssym);
212                 if (ssym->nl_class && ssym->nl_class!=tagkind) {
213                         defsym = ssym;
214                         redec();
215                         ssym = pushdecl(ssym);
216                 }
217                 if (ssym->nl_class==0) {
218                         ssym->nl_class = tagkind;
219  /*                     ssym->nl_strp = (union str *)Dblock(sizeof(struct SS));*/
220  stype = (struct stype *)Dblock(sizeof(struct stype));
221  stype->st_id = STRUCT;
222                         /*ssym->nl_strp->S.ssize*/stype->st_ssize = 0;
223                         /*ssym->nl_strp->S.memlist*/stype->st_memlist = NULL;
224  /*ssym->nl_strp = (union str *)&stype->st_S;*/
225  ssym->nl_dtype = (struct type *)stype;
226                 }
227  /*             strp = ssym->nl_strp;*/
228  else
229   stype = (struct stype *)ssym->nl_dtype;
230         } else {
231  /*             strp = (union str *)Dblock(sizeof(struct SS));*/
232  stype = (struct stype *)Dblock(sizeof(struct stype));
233  stype->st_id = STRUCT;
234                 /*strp->S.ssize*/stype->st_ssize = 0;
235                 /*strp->S.memlist*/stype->st_memlist = NULL;
236         }
237         mosflg = 0;
238         if (o != LBRACE) {
239                 if (ssym==0)
240                         goto syntax;
241                 if (ssym->nl_class!=tagkind)
242                         error0("Bad structure/union/enum name");
243                 peeksym = o;
244         } else {
245                 ds = defsym;
246                 mosflg = 0;
247                 savebits = bitoffs;
248                 savememlist = memlist;
249                 savesparent = sparent;
250                 savenmems = nmems;
251                 memlist = mems;
252                 sparent = /*strp*/(union str *)&stype->st_S;
253                 nmems = 2;
254                 bitoffs = 0;
255                 if (kind==ENUM) {
256  /*                     typer.nl_type = INT;
257                         typer.nl_strp = strp;*/
258  /* strp above seems to be vestigial, I don't think it is ever referenced */
259                         declare(ENUM, /*&typer*/&t_int, 0);
260                 } else
261                         elsize = declist(kind==UNION?MOU:MOS);
262                 bitoffs = savebits;
263 #if 1 /* just save a bit of string space */
264                 if (/*strp->S.ssize*/stype->st_ssize) {
265                         defsym = ssym;
266                         redec();
267                 }
268                 defsym = ds;
269 #else
270                 defsym = ds;
271                 if (strp->S.ssize)
272                         error0("%s redeclared", ssym->nl_name);
273 #endif
274                 /*strp->S.ssize*/stype->st_ssize = elsize;
275                 *memlist++ = NULL;
276                 /*strp->S.memlist*/stype->st_memlist = (struct nmlist **)Dblock((memlist-mems)*sizeof(*memlist));
277                 for (o=0; &mems[o] != memlist; o++)
278                         /*strp->S.memlist*/stype->st_memlist[o] = mems[o];
279                 memlist = savememlist;
280                 sparent = savesparent;
281                 nmems = savenmems;
282                 if ((o = symbol()) != RBRACE)
283                         goto syntax;
284         }
285  /*fprintf(stderr, "stype=%p,%p\n", stype, &stype->st_S);*/
286         return(/*strp*/stype);
287    syntax:
288         decsyn(o);
289         return(0);
290 }
291
292 /*
293  * Process a comma-separated list of declarators
294  */
295 int declare(askw, tptr, offset) int askw; struct /*nmlist*/type *tptr; int offset; {
296         register unsigned o;
297         register int skw, isunion;
298         struct nmlist abs, *aptr;
299  static struct type t_char = {CHAR};
300
301         skw = askw;
302         isunion = 0;
303         if (skw==MOU) {
304                 skw = MOS;
305                 isunion++;
306                 mosflg = FMOS;
307                 if ((peeksym=symbol()) == SEMI) {
308                         o = length(/*(struct node *)*/tptr);
309                         if (o>offset)
310                                 offset = o;
311                 }
312         }
313         do {
314                 if (skw==ENUM && (peeksym=symbol())==RBRACE) {
315                         o = peeksym;
316                         peeksym = -1;
317                         break;
318                 }
319                 if (skw == MOS) {
320                         abs.nl_class = 0;
321                         abs.nl_flag = 0;
322  /*                     abs.nl_type = 0;
323                         abs.nl_subsp = 0;
324                         abs.nl_strp = 0;*/
325  abs.nl_dtype = NULL;
326                         abs.nl_nextnm = 0;
327                         abs.nl_sparent = 0;
328                         abs.nl_blklev = blklev;
329                         abs.nl_name = "<none>";
330                         aptr = &abs;
331                 } else
332                         aptr = NULL;
333                 o = decl1(skw, tptr, isunion?0:offset, aptr);
334                 if (isunion) {
335                         o += align(/*CHAR*/&t_char, o, 0);
336                         if (o>offset)
337                                 offset = o;
338                 } else
339                         offset += o;
340         } while ((o=symbol()) == COMMA);
341         if (o==RBRACE) {
342                 peeksym = o;
343                 o = SEMI;
344         }
345         if (o!=SEMI && (o!=RPARN || skw!=ARG1))
346                 decsyn(o);
347         return(offset);
348 }
349
350 /*
351  * Process a single declarator
352  */
353 /* convert detailed type description to old type description */
354 void XXXdumptype(dtype) struct type *dtype; {
355  static char *basic_types[] = {
356   "INT",
357   "CHAR",
358   "FLOAT",
359   "DOUBLE",
360   "STRUCT",
361   "RSTRUCT",
362   "LONG",
363   "UNSIGN",
364   "UNCHAR",
365   "UNLONG",
366   "VOID",
367   "REF",
368   "BITFLD"
369  };
370  switch (dtype->t_id) {
371  case REF | PTR:
372   fprintf(stderr, "PTR");
373   goto reftype;
374  case REF | FUNC:
375 #define fdtype ((struct ftype *)dtype)
376   fprintf(stderr, "FUNC");
377   /*if (fdtype->ft_arglist) {
378    int i;
379    fputc('(', stderr);
380    for (i = 0; fdtype->ft_arglist[i]; ++i) {
381     if (i)
382      fputc(',', stderr);
383     fprintf(stderr, "%s", fdtype->ft_arglist[i]->nl_name);
384    }
385    fputc(')', stderr);
386   }*/
387   goto reftype;
388 #undef fdtype
389  case REF | ARRAY:
390   fprintf(stderr, "ARRAY(%d)", ((struct atype *)dtype)->at_nelt);
391  reftype:
392   fputc(',', stderr);
393   XXXdumptype(((struct rtype *)dtype)->rt_reftype);
394   break;
395  default:
396   fprintf(stderr, "%s", basic_types[dtype->t_id]);
397   break;
398  }
399 }
400 int XXXoldtype(dtype, dimp, strp) struct type *dtype; struct tdim *dimp; struct SS **strp; {
401  int type;
402  switch (dtype->t_id) {
403  case REF | PTR:
404   type = XXXoldtype(((struct rtype *)dtype)->rt_reftype, dimp, strp);
405   if (type & BIGTYPE) {
406    typov();
407    type = 0;
408   }
409   type = (type & TYPE) | (type & ~TYPE) << TYLEN | PTR;
410   break;
411  case REF | FUNC:
412   type = XXXoldtype(((struct ftype *)dtype)->ft_reftype, dimp, strp);
413   if (type & BIGTYPE) {
414    typov();
415    type = 0;
416   }
417   type = (type & TYPE) | (type & ~TYPE) << TYLEN | FUNC;
418   break;
419  case REF | ARRAY:
420   if (dimp->rank>=5) {
421    error0("Rank too large");
422    dimp->rank = 4;
423   }
424   dimp->dimens[dimp->rank++] = ((struct atype *)dtype)->at_nelt;
425   type = XXXoldtype(((struct atype *)dtype)->at_reftype, dimp, strp);
426   if (type & BIGTYPE) {
427    typov();
428    type = 0;
429   }
430   type = (type & TYPE) | (type & ~TYPE) << TYLEN | ARRAY;
431   break;
432  case STRUCT:
433   *strp = &((struct stype *)dtype)->st_S;
434   type = STRUCT;
435   break;
436  case BITFLD:
437   *strp = NULL;
438   type = UNSIGN;
439   break;
440  default:
441   *strp = NULL;
442   type = dtype->t_id;
443   break;
444  }
445  return type;
446 }
447 int decl1(askw, atptr, offset, absname) int askw; struct /*nmlist*/type *atptr; int offset; struct nmlist *absname; {
448         int t1, a, elsize;
449         register int skw;
450  struct rtype rtype, *tail;
451  /*     int type;*/
452         register struct nmlist *dsym;
453  /*     register struct nmlist *tptr;
454         struct tdim dim;*/
455  /*struct SS *strp;
456         int *dp;*/
457         int isinit;
458
459         skw = askw;
460  /*     tptr = atptr;*/
461         mosflg = skw==MOS? FMOS: 0;
462  /*     dim.rank = 0;*/
463         if (((peeksym=symbol())==SEMI || peeksym==RPARN) && absname==NULL)
464                 return(0);
465         /*
466          * Filler field
467          */
468         if (peeksym==COLON && skw==MOS) {
469                 peeksym = -1;
470                 t1 = conexp();
471                 if (t1<0) {
472                         error0("Negative field width");
473                         t1 = 0;
474                 }
475                 elsize = align(/*tptr->nl_type*/atptr, offset, t1);
476                 bitoffs += t1;
477                 return(elsize);
478         }
479  /*     t1 = getype(&dim, absname);
480         if (t1 == -1)
481                 return(0);*/
482  /* we will construct a type which looks like a pointer to the real type, */
483  /* this is so that getype() can check the enclosing type, if REF | ARRAY */
484  /* then dimension must be specified, e.g. a[][10] is OK, but a[][] is not */
485  rtype.rt_id = REF | PTR;
486  tail = getype(&rtype, absname!=NULL);
487  if (tail)
488   tail->rt_reftype = atptr; /* otherwise, had error and set tail to int */
489  /*fprintf(stderr, "name %s type ", defsym ? defsym->nl_name : absname ? absname->nl_name : "???");
490  XXXdumptype(rtype.rt_reftype);
491  fprintf(stderr, "\n");*/
492         if (defsym)
493                 absname = NULL;
494  /*     if (tptr->nl_subsp) {
495                 type = tptr->nl_type;
496                 for (a=0; type&XTYPE;) {
497                         if ((type&XTYPE)==ARRAY)
498                                 dim.dimens[dim.rank++] = tptr->nl_subsp[a++];
499                         type >>= TYLEN;
500                 }
501         }
502         type = tptr->nl_type & ~TYPE;
503         while (t1&XTYPE) {
504                 if (type&BIGTYPE) {
505                         typov();
506                         type = t1 = 0;
507                 }
508                 type = type<<TYLEN | (t1 & XTYPE);
509                 t1 >>= TYLEN;
510         }
511         type |= tptr->nl_type&TYPE;*/
512         if (/*(type&XTYPE) == FUNC*/rtype.rt_reftype->t_id == (REF | FUNC)) {
513                 if (skw==AUTO)
514                         skw = EXTERN;
515                 if ((skw!=EXTERN && skw!=TYPEDEF) && absname==NULL)
516                         error0("Bad func. storage class");
517         }
518         if (defsym)
519                 dsym = defsym;
520         else if (absname)
521                 dsym = absname;
522         else {
523                 error0("Name required in declaration");
524                 return(0);
525         }
526         if (defsym)
527         if (dsym->nl_blklev<blklev || dsym->nl_class==MOS && skw==MOS) {
528                 if (skw==MOS && dsym->nl_sparent==sparent)
529                         redec();
530                 defsym = dsym;
531                 if (skw==EXTERN) {
532                         for (; dsym!=NULL; dsym = dsym->nl_nextnm) {
533                                 if (dsym->nl_class==EXTERN
534                                  && strcmp(dsym->nl_name, defsym->nl_name)==0) {
535                                         defsym = dsym;
536                                         break;
537                                 }
538                         }
539                         dsym = defsym;
540                 } else
541                         defsym = dsym = pushdecl(dsym);
542         }
543  /* old way */
544  /*     if (dim.rank == 0)
545                 dsym->nl_subsp = NULL;
546         else {
547                 *//*
548                  * If an array is declared twice, make sure the declarations
549                  * agree in dimension.  This happens typically when a .h
550                  * and .c file both declare a variable.
551                  *//*
552                 if (dsym->nl_subsp) {
553                         for (a=0, t1 = dsym->nl_type;
554                             a<dim.rank && (t1&XTYPE)==ARRAY);
555                             a++, t1 >>= TYLEN)
556                                 *//*
557                                  * If we haven't seen a declaration for this
558                                  * dimension yet, take what's been given now.
559                                  *//*
560                                 if (!dsym->nl_subsp[a])
561                                         dsym->nl_subsp[a] = dim.dimens[a];
562                                 else if (dim.dimens[a]
563                                     && dim.dimens[a] != dsym->nl_subsp[a])
564                                         redec();
565                         if (a<dim.rank || (t1&XTYPE)==ARRAY)
566                                 redec();
567                 } else {
568                         dp = (int *)Dblock(dim.rank*sizeof(dim.rank));
569                         for (a=0; a<dim.rank; a++)
570                                 dp[a] = dim.dimens[a];
571                         dsym->nl_subsp = dp;
572                 }
573         }
574         if (!(dsym->nl_class==0
575            || ((skw==ARG||skw==AREG) && dsym->nl_class==ARG1)
576            || (skw==EXTERN && dsym->nl_class==EXTERN && dsym->nl_type==type))) {
577                 redec();
578                 goto syntax;
579         }
580         if (dsym->nl_class && (dsym->nl_type&TYPE)==STRUCT && (type&TYPE)==STRUCT)
581                 if (dsym->nl_strp != *//*tptr->nl_strp*//*(union str *)&((struct stype *)tptr)->st_S) {
582                         error0("structure redeclaration");
583                 }
584         dsym->nl_type = type;
585         if (tptr->nl_strp)
586                 dsym->nl_strp = tptr->nl_strp;*/
587  /* new way */
588  if (skw==EXTERN && dsym->nl_class==EXTERN) {
589   /* got redeclaration of previously declared extern symbol */
590   /* compare types, picking up any new dimension information */
591   struct type *dt, *dt1;
592   for (
593    dt = rtype.rt_reftype, dt1 = dsym->nl_dtype;
594    (t1 = dt->t_id) == dt1->t_id;
595    dt=((struct rtype *)dt)->rt_reftype, dt1=((struct rtype *)dt1)->rt_reftype
596   )
597    switch (t1) {
598    case REF | PTR:
599    case FUNC | PTR:
600     break;
601    case REF | ARRAY:
602 #define adt ((struct atype *)dt)
603 #define adt1 ((struct atype *)dt1)
604     if (!adt1->at_nelt)
605      adt1->at_nelt = adt->at_nelt;
606     else if (adt->at_nelt && adt->at_nelt != adt1->at_nelt)
607      redec();
608     break;
609 #undef adt
610 #undef adt1
611    case STRUCT:
612     if (dt != dt1)
613      error0("structure redeclaration");
614     /* fallthru */
615    default:
616     goto done;
617    }
618   redec();
619  done:
620   ;
621  }
622  else if (dsym->nl_class==0 || (skw==ARG||skw==AREG) && dsym->nl_class==ARG1)
623   /* new declaration, or real declaration of K&R function argument */
624   /* just clobber the type, no type compatibility check needed */
625   dsym->nl_dtype = rtype.rt_reftype;
626  else {
627   redec();
628   goto syntax;
629  }
630  /*dim.rank = 0;
631  dsym->nl_type = XXXoldtype(dsym->nl_dtype, &dim, (struct SS **)&dsym->nl_strp);
632  if (dim.rank && dsym->nl_subsp == 0)
633   dsym->nl_subsp = (int *)Dblock(dim.rank*sizeof(dim.rank));
634  for (a=0; a<dim.rank; a++)
635   dsym->nl_subsp[a] = dim.dimens[a];*/
636         if (skw==TYPEDEF) {
637                 dsym->nl_class = TYPEDEF;
638                 return(0);
639         }
640         if (skw==ARG1) {
641                 if (paraml==NULL)
642                         paraml = dsym;
643                 else
644                         parame->nl_sparent = (union str *)dsym;
645                 parame = dsym;
646                 dsym->nl_class = skw;
647                 return(0);
648         }
649         elsize = 0;
650         if (skw==MOS) {
651  /*fprintf(stderr, "mos %p name %s\n", dsym, dsym->nl_name);*/
652                 elsize = length(/*(struct node *)dsym*/dsym->nl_dtype);
653                 if ((peeksym = symbol())==COLON) {
654                         elsize = 0;
655                         peeksym = -1;
656                         t1 = conexp();
657                         a = align(/*type*/dsym->nl_dtype, offset, t1);
658  /*fprintf(stderr, "a bitfield strp %p\n", dsym->nl_strp);*/
659                         if (dsym->/*nl_flag&FFIELD*/nl_dtype->t_id == BITFLD) {
660                                 if (/*dsym->nl_strp->F.bitoffs*/((struct btype *)dsym->nl_dtype)->bt_bitoffs!=bitoffs
661                                  || /*dsym->nl_strp->F.flen*/((struct btype *)dsym->nl_dtype)->bt_flen!=t1)
662                                         redec();
663                         } else {
664  /*                             dsym->nl_strp = (union str *)Dblock(sizeof(struct FS));*/
665  struct btype *btp = (struct btype *)Dblock(sizeof(struct btype));
666  btp->bt_id = BITFLD;
667  btp->bt_flen = t1;
668  btp->bt_bitoffs = bitoffs;
669  /*dsym->nl_strp = (union str *)&btp->bt_F;*/
670  dsym->nl_dtype = (struct type *)btp;
671                         }
672  /*fprintf(stderr, "b bitfield strp %p\n", dsym->nl_strp);*/
673  /*                     dsym->nl_flag |= FFIELD;
674                         dsym->nl_strp->F.bitoffs = bitoffs;
675                         dsym->nl_strp->F.flen = t1;*/
676                         bitoffs += t1;
677                 } else
678                         a = align(/*type*/dsym->nl_dtype, offset, 0);
679                 elsize += a;
680                 offset += a;
681                 if (++nmems >= NMEMS) {
682                         error0("Too many structure members");
683                         nmems -= NMEMS/2;
684                         memlist -= NMEMS/2;
685                 }
686                 if (a)
687                         *memlist++ = &structhole;
688                 dsym->nl_offset = offset;
689                 *memlist++ = dsym;
690                 dsym->nl_sparent = sparent;
691         }
692         if (skw==REG)
693                 if ((dsym->nl_offset = goodreg(dsym)) < 0)
694                         skw = AUTO;
695         dsym->nl_class = skw;
696         isinit = 0;
697         if ((a=symbol()) == ASSIGN)
698                 isinit++;
699         else
700                 peeksym = a;
701         if (skw==AUTO) {
702         /*      if (STAUTO < 0) {       */
703  /*fprintf(stderr, "%s autolen %d -> ", dsym->nl_name, autolen);*/
704                         autolen -= rlength(/*(struct node *)dsym*/dsym->nl_dtype);
705                         dsym->nl_offset = autolen;
706                         if (autolen < maxauto)
707                                 maxauto = autolen;
708  /*fprintf(stderr, "%d maxauto %d\n", autolen, maxauto);*/
709         /*      } else {                        */
710         /*              dsym->nl_offset = autolen;      */
711         /*              autolen += rlength(*//*(struct node *)dsym*//*dsym->nl_dtype);  */
712         /*              if (autolen > maxauto)          */
713         /*                      maxauto = autolen;      */
714         /*      }                       */
715                 if (isinit)
716                         cinit(dsym, 0, AUTO);
717                 isinit = 0;
718         } else if (skw==STATIC) {
719                 dsym->nl_offset = isn0;
720                 if (isinit) {
721                         outcode("BBN", DATA, LABEL, isn0++);
722                         if (cinit(dsym, 1, STATIC) & ALIGN)
723                                 outcode("B", EVEN);
724                 } else
725                         outcode("BBNBN", BSS, LABEL, isn0++, SSPACE,
726                           rlength(/*(struct node *)dsym*/dsym->nl_dtype));
727                 outcode("B", PROG);
728                 isinit = 0;
729         } else if (skw==REG && isinit) {
730                 cinit(dsym, 0, REG);
731                 isinit = 0;
732         } else if (skw==ENUM) {
733                 if (/*type*/dsym->nl_dtype->t_id!=INT)
734                         error0("Illegal enumeration %s", dsym->nl_name);
735                 dsym->nl_class = ENUMCON;
736                 dsym->nl_offset = offset;
737                 if (isinit)
738                         cinit(dsym, 0, ENUMCON);
739                 elsize = dsym->nl_offset-offset+1;
740                 isinit = 0;
741         }
742         if (absname==0)
743                 prste(dsym);
744         if (isinit)
745                 peeksym = ASSIGN;
746 syntax:
747         return(elsize);
748 }
749
750 /*
751  * Push down an outer-block declaration
752  * after redeclaration in an inner block.
753  */
754 struct nmlist *pushdecl(sp) register struct nmlist *sp; {
755         register struct nmlist *nsp, **hsp;
756
757         nsp = (struct nmlist *)Dblock(sizeof(struct nmlist));
758         *nsp = *sp;
759         nsp->nl_class = 0;
760         nsp->nl_flag &= FKIND;
761  /*     nsp->nl_type = 0;*/
762  nsp->nl_dtype = NULL;
763         nsp->nl_offset = 0;
764         nsp->nl_blklev = blklev;
765  /*     nsp->nl_strp = NULL;
766         nsp->nl_subsp = NULL;*/
767         nsp->nl_sparent = NULL;
768         hsp = &hshtab[hash(sp->nl_name)];
769         nsp->nl_nextnm = *hsp;
770         *hsp = nsp;
771         return(nsp);
772 }
773
774 /*
775  * Read a declarator and get the implied type
776  */
777 /*int getype(dimp, absname) register struct tdim *dimp; struct nmlist *absname;*/ struct rtype *getype(tail, anonok) struct rtype *tail; int anonok; {
778  /*     static struct nmlist argtype;*/
779  static struct type t_int = {INT};
780  /*     int type;*/
781  struct rtype *newtail;
782         register int o;
783         register struct nmlist *ds;
784
785         defsym = 0;
786  /*     type = 0;*/
787         switch(o=symbol()) {
788
789         case TIMES:
790  /*             type = getype(dimp, absname);
791                 if (type==-1)
792                         return(type);*/
793  tail = getype(tail, anonok);
794  if (tail==NULL)
795   return(NULL);
796  /*             if (type&BIGTYPE) {
797                         typov();
798                         type = 0;
799                 }
800                 return(type<<TYLEN | PTR);*/
801  newtail = (struct rtype *)Dblock(sizeof(struct rtype));
802  newtail->rt_id = REF | PTR;
803  tail->rt_reftype = (struct type *)newtail;
804  return newtail;
805
806         case LPARN:
807                 if (/*absname==NULL*/!anonok || nextchar()!=')') {
808  /*                     type = getype(dimp, absname);
809                         if (type==-1)
810                                 return(type);*/
811  tail = getype(tail, anonok);
812  if (tail==NULL)
813   return(NULL);
814                         if ((o=symbol()) != RPARN)
815                                 goto syntax;
816                         goto getf;
817                 }
818
819         default:
820                 peeksym = o;
821                 if (/*absname*/anonok)
822                         goto getf;
823                 break;
824
825         case NAME:
826                 defsym = /*ds =*/ csym;
827         getf:
828                 switch(o=symbol()) {
829
830                 case LPARN:
831                         if (blklev==0) {
832                                 blklev++;
833                                 ds = defsym;
834                                 declare(ARG1, &/*argtype*/t_int, 0);
835                                 defsym = ds;
836                                 blklev--;
837                         } else
838                                 if ((o=symbol()) != RPARN)
839                                         goto syntax;
840  /*                     if (type&BIGTYPE) {
841                                 typov();
842                                 type = 0;
843                         }
844                         type = type<<TYLEN | FUNC;*/
845 #define fnewtail (*(struct ftype **)&newtail)
846  fnewtail = (struct ftype *)Dblock(sizeof(struct ftype));
847  fnewtail->ft_id = REF | FUNC;
848  fnewtail->ft_arglist = NULL;
849  tail->rt_reftype = (struct type *)fnewtail;
850  tail = (struct rtype *)fnewtail;
851 #undef fnewtail
852                         goto getf;
853
854                 case LBRACK:
855  /*                     if (dimp->rank>=5) {
856                                 error0("Rank too large");
857                                 dimp->rank = 4;
858                         }*/
859                         if ((o=symbol()) != RBRACK) {
860                                 peeksym = o;
861                                 ds = defsym;
862                                 cval = conexp();
863                                 defsym = ds;
864                                 if ((o=symbol())!=RBRACK)
865                                         goto syntax;
866                         } else {
867  /*                             if (dimp->rank!=0)*/
868  if (tail->rt_id == (REF | ARRAY))
869                                         error0("Null dimension");
870                                 cval = 0;
871                         }
872  /*                     dimp->dimens[dimp->rank++] = cval;
873                         if (type&BIGTYPE) {
874                                 typov();
875                                 type = 0;
876                         }
877                         type = type<<TYLEN | ARRAY;*/
878 #define anewtail (*(struct atype **)&newtail)
879  anewtail = (struct atype *)Dblock(sizeof(struct atype));
880  anewtail->at_id = REF | ARRAY;
881  anewtail->at_nelt = cval;
882  tail->rt_reftype = (struct type *)anewtail;
883  tail = (struct rtype *)anewtail;
884 #undef anewtail
885                         goto getf;
886                 }
887                 peeksym = o;
888  /*             return(type);*/
889  return(tail);
890         }
891 syntax:
892         decsyn(o);
893  /*     return(-1);*/
894  tail->rt_reftype = &t_int;
895  return(NULL);
896 }
897
898 /*
899  * More bits required for type than allowed.
900  */
901 void typov() {
902         error0("Type is too complicated");
903 }
904
905 /*
906  * Enforce alignment restrictions in structures,
907  * including bit-field considerations.
908  */
909 /* really means make sure aflen bits can be allocated after current position */
910 /* takes size in bytes and the global bitoffs, returns size increase in bytes */
911 int align(type, offset, aflen) /*int*/struct type *type; int offset; int aflen; {
912         register int a, /*t,*/ flen;
913  register struct type *t;
914         char *ftl;
915
916         flen = aflen;
917         a = offset;
918  /*     t = type;*/
919         ftl = "Field too long";
920         if (flen==0) {
921                 a += (NBPC+bitoffs-1) / NBPC;
922                 bitoffs = 0;
923         }
924  /*     while ((t&XTYPE)==ARRAY)
925                 t = decref0(t);*/
926  for (t = type; t->t_id == (REF | ARRAY); t = ((struct atype *)t)->at_reftype)
927    ;
928         if (/*t*/t->t_id!=CHAR && /*t*/t->t_id!=UNCHAR) {
929                 a = (a+ALIGN) & ~ALIGN;
930                 if (a>offset)
931                         bitoffs = 0;
932         }
933         if (flen) {
934                 if (/*type*/type->t_id==INT || /*type*/type->t_id==UNSIGN) {
935                         if (flen > NBPW)
936                                 error0(ftl);
937                         if (flen+bitoffs > NBPW) {
938                                 bitoffs = 0;
939                                 a += NCPW;
940                         }
941                 } else if (/*type*/type->t_id==CHAR || /*type*/type->t_id==UNCHAR) {
942                         if (flen > NBPC)
943                                 error0(ftl);
944                         if (flen+bitoffs > NBPC) {
945                                 bitoffs = 0;
946                                 a += 1;
947                         }
948                 } else
949                         error0("Bad type for field");
950         }
951         return(a-offset);
952 }
953
954 /*
955  * Complain about syntax error in declaration
956  */
957 void decsyn(o) int o; {
958         error0("Declaration syntax");
959         errflush(o);
960 }
961
962 /*
963  * Complain about a redeclaration
964  */
965 void redec() {
966         error0("%s redeclared", defsym->nl_name);
967 }
968
969 /*
970  * Determine if a variable is suitable for storage in
971  * a register; if so return the register number
972  */
973 int goodreg(hp) struct nmlist *hp; {
974  /*     int type;*/
975  struct type *dtype;
976
977  /*     type = hp->nl_type;*/
978  dtype = hp->nl_dtype;
979         if ((/*type*/dtype->t_id!=INT && /*type*/dtype->t_id!=UNSIGN && /*(type&XTYPE)==0*/dtype->t_id!=(REF|PTR))
980          || /*(type&XTYPE)>PTR ||*/ regvar<3)
981                 return(-1);
982         return(--regvar);
983 }