URI:
       decl.c - scc - simple c99 compiler
  HTML git clone git://git.simple-cc.org/scc
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
   DIR README
   DIR LICENSE
       ---
       decl.c (19239B)
       ---
            1 #include <assert.h>
            2 #include <limits.h>
            3 #include <stdarg.h>
            4 #include <stdlib.h>
            5 #include <string.h>
            6 
            7 #include <scc/cstd.h>
            8 #include <scc/scc.h>
            9 #include "cc1.h"
           10 
           11 #define NOSCLASS  0
           12 
           13 #define NOREP 0
           14 #define REP 1
           15 #define QUIET   1
           16 #define NOQUIET 0
           17 
           18 #define NR_DCL_TYP (NR_DECLARATORS+NR_FUNPARAM)
           19 #define NR_DCL_SYM (NR_DECLARATORS+NR_FUNPARAM+1)
           20 
           21 struct declarators {
           22         unsigned nr;
           23         unsigned ns;
           24         struct decl *dcl;
           25         unsigned nr_types;
           26         Type **tpars;
           27         Symbol **pars;
           28         struct declarator {
           29                 unsigned char op;
           30                 long long  nelem;
           31                 Symbol *sym;
           32                 Type **tpars;
           33                 Symbol **pars;
           34         } d [NR_DECLARATORS];
           35 };
           36 
           37 struct decl {
           38         unsigned ns;
           39         int sclass;
           40         int qualifier;
           41         Symbol *sym;
           42         Type *type;
           43         Type *parent;
           44         Symbol **pars;
           45         Symbol *bufpars[NR_DCL_SYM];
           46         Type *buftpars[NR_DCL_TYP];
           47 };
           48 
           49 
           50 static void
           51 endfundcl(Type *tp, Symbol **pars)
           52 {
           53         /*
           54          * If endfundcl is called from a type built from a typedef then
           55          * we do not have any parameters because in that case we only
           56          * care about the type.
           57          */
           58         if (pars) {
           59                 if ((tp->prop&TK_R) != 0 && *pars)
           60                         warn("parameter names (without types) in function declaration");
           61 
           62                 /* avoid non used warnings in prototypes */
           63                 while (*pars)
           64                         (*pars++)->flags |= SUSED;
           65                 popctx();
           66         }
           67 }
           68 
           69 static void
           70 push(struct declarators *dp, int op, ...)
           71 {
           72         va_list va;
           73         unsigned n;
           74         struct declarator *p;
           75 
           76         va_start(va, op);
           77         if ((n = dp->nr++) == NR_DECLARATORS)
           78                 error("too many declarators");
           79 
           80         p = &dp->d[n];
           81         p->op = op;
           82         p->tpars = NULL;
           83 
           84         switch (op) {
           85         case ARY:
           86                 p->nelem = va_arg(va, long long);
           87                 break;
           88         case KRFTN:
           89         case FTN:
           90                 p->nelem = va_arg(va, unsigned);
           91                 p->tpars = va_arg(va, Type **);
           92                 p->pars = va_arg(va, Symbol **);
           93                 break;
           94         case IDEN:
           95                 p->sym = va_arg(va, Symbol *);
           96                 break;
           97         }
           98         va_end(va);
           99 }
          100 
          101 static int
          102 pop(struct declarators *dp, struct decl *dcl)
          103 {
          104         struct declarator *p;
          105 
          106         if (dp->nr == 0)
          107                 return 0;
          108 
          109         p = &dp->d[--dp->nr];
          110         if (p->op == IDEN) {
          111                 dcl->sym = p->sym;
          112                 return 1;
          113         }
          114 
          115         /*
          116          * We have a type derived from a function type. We don't care
          117          * about the parameters because they were used only in the
          118          * process of building a final type. Prototype arguments are
          119          * discarded in funbody() because the final type of the decl
          120          * is an actual function.
          121          */
          122         if (dcl->type->op == FTN)
          123                 endfundcl(dcl->type, dcl->pars);
          124         dcl->pars = p->pars;
          125 
          126         dcl->type = mktype(dcl->type, p->op, p->nelem, p->tpars);
          127         return 1;
          128 }
          129 
          130 static void
          131 arydcl(struct declarators *dp)
          132 {
          133         Node *np = NULL;
          134         long long n = 0;
          135         int ns;
          136 
          137         ns = namespace;
          138         namespace = NS_IDEN;
          139         expect('[');
          140         if (yytoken != ']') {
          141                 if ((np = constexpr()) == NULL) {
          142                         errorp("invalid storage size");
          143                 } else {
          144                         if ((n = np->sym->u.i) <= 0) {
          145                                 errorp("array size is not a positive number");
          146                                 n = 1;
          147                         }
          148                         freetree(np);
          149                 }
          150         }
          151         namespace = ns;
          152         expect(']');
          153 
          154         push(dp, ARY, n);
          155 }
          156 
          157 static int
          158 empty(Symbol *sym, Type *tp, int param)
          159 {
          160         if (!sym->name) {
          161                 sym->type = tp;
          162                 switch (tp->op) {
          163                 default:
          164                          /* warn if it is not a parameter */
          165                         if (!param)
          166                                 warn("empty declaration");
          167                 case STRUCT:
          168                 case UNION:
          169                 case ENUM:
          170                         return 1;
          171                 }
          172         }
          173         return 0;
          174 }
          175 
          176 static void
          177 bad_storage(Type *tp, char *name)
          178 {
          179         if (tp->op != FTN)
          180                 errorp("incorrect storage class for file-scope declaration");
          181         else
          182                 errorp("invalid storage class for function '%s'", name);
          183 }
          184 
          185 static Symbol *
          186 redcl(Symbol *sym, Type *tp, int sclass)
          187 {
          188         int flags;
          189         char *name = sym->name;
          190 
          191         if (!eqtype(sym->type, tp, EQUIV)) {
          192                 errorp("conflicting types for '%s'", name);
          193                 return sym;
          194         }
          195 
          196         /* we prefere ansi types over k&r types */
          197         if ((sym->type->prop & TK_R) == 0 && (tp->prop & TK_R) != 0)
          198                 sym->type = tp;
          199 
          200         if (sym->token == TYPEIDEN && sclass != TYPEDEF ||
          201             sym->token != TYPEIDEN && sclass == TYPEDEF) {
          202                 goto redeclaration;
          203         }
          204         if (curctx != GLOBALCTX && tp->op != FTN) {
          205                 /* is it the redeclaration of a local variable? */
          206                 if ((sym->flags & SEXTERN) && sclass == EXTERN)
          207                         return sym;
          208                 goto redeclaration;
          209         }
          210 
          211         flags = sym->flags;
          212         switch (sclass) {
          213         case REGISTER:
          214         case AUTO:
          215                 bad_storage(tp, name);
          216                 break;
          217         case NOSCLASS:
          218                 if ((flags & SPRIVATE) == 0) {
          219                         if (flags & SEXTERN)
          220                                 flags &= ~(SEXTERN|SEMITTED);
          221                         flags |= SGLOBAL;
          222                         break;
          223                 }
          224                 errorp("non-static declaration of '%s' follows static declaration",
          225                        name);
          226                 break;
          227         case TYPEDEF:
          228                 /* Only C11 allows multiple definitions of a typedef. */
          229                 goto redeclaration;
          230         case EXTERN:
          231                 break;
          232         case STATIC:
          233                 if ((flags & (SGLOBAL|SEXTERN)) == 0) {
          234                         flags |= SPRIVATE;
          235                         break;
          236                 }
          237                 errorp("static declaration of '%s' follows non-static declaration",
          238                        name);
          239                 break;
          240         }
          241         sym->flags = flags;
          242 
          243         return sym;
          244 
          245 redeclaration:
          246         errorp("redeclaration of '%s'", name);
          247         return sym;
          248 }
          249 
          250 static Symbol *
          251 identifier(struct decl *dcl)
          252 {
          253         Symbol *sym = dcl->sym;
          254         Type *tp = dcl->type;
          255         int sclass = dcl->sclass;
          256         char *name = sym->name;
          257 
          258         if (empty(sym, tp, 0))
          259                 return sym;
          260 
          261         /* TODO: Add warning about ANSI limits */
          262         if (!(tp->prop & TDEFINED)                &&
          263             sclass != EXTERN && sclass != TYPEDEF &&
          264             !(tp->op == ARY && yytoken == '=')) {
          265                 errorp("declared variable '%s' of incomplete type", name);
          266         }
          267 
          268         if (tp->op == FTN) {
          269                 if (sclass == NOSCLASS)
          270                         sclass = EXTERN;
          271                 if (!strcmp(name, "main") && tp->type != inttype) {
          272                         errorp("main shall be defined with a return type of int");
          273                 }
          274         }
          275 
          276         if (strcmp(name, "__func__") == 0)
          277                 errorp("__func__ is a reserved variable name");
          278 
          279         if (sym->flags & SDECLARED) {
          280                 sym = redcl(dcl->sym, tp, sclass);
          281         } else {
          282                 int flags = sym->flags | SDECLARED;
          283 
          284                 sym->type = tp;
          285 
          286                 switch (sclass) {
          287                 case REGISTER:
          288                 case AUTO:
          289                         if (curctx != GLOBALCTX && tp->op != FTN) {
          290                                 flags |= (sclass == REGISTER) ? SREGISTER : SAUTO;
          291                                 break;
          292                         }
          293                         bad_storage(tp, name);
          294                 case NOSCLASS:
          295                         if (tp->op == FTN)
          296                                 flags |= SEXTERN;
          297                         else
          298                                 flags |= (curctx == GLOBALCTX) ? SGLOBAL : SAUTO;
          299                         break;
          300                 case EXTERN:
          301                         flags |= SEXTERN;
          302                         break;
          303                 case STATIC:
          304                         flags |= (curctx == GLOBALCTX) ? SPRIVATE : SLOCAL;
          305                         break;
          306                 case TYPEDEF:
          307                         flags |= STYPEDEF;
          308                         sym->u.token = sym->token = TYPEIDEN;
          309                         break;
          310                 }
          311                 sym->flags = flags;
          312         }
          313 
          314         if (accept('='))
          315                 initializer(sym, sym->type);
          316         if (!(sym->flags & (SGLOBAL|SEXTERN)) && tp->op != FTN)
          317                 sym->flags |= SDEFINED;
          318         if (sym->token == IDEN && tp->op != FTN)
          319                 emit(ODECL, sym);
          320         return sym;
          321 }
          322 
          323 static Symbol *
          324 parameter(struct decl *dcl)
          325 {
          326         Symbol *sym = dcl->sym;
          327         Type *funtp = dcl->parent, *tp = dcl->type;
          328         char *name = sym->name;
          329         int flags;
          330 
          331         flags = 0;
          332         switch (dcl->sclass) {
          333         case STATIC:
          334         case EXTERN:
          335         case AUTO:
          336                 errorp("bad storage class in function parameter");
          337                 break;
          338         case REGISTER:
          339                 flags |= SREGISTER;
          340                 break;
          341         case NOSCLASS:
          342                 flags |= SAUTO;
          343                 break;
          344         }
          345 
          346         switch (tp->op) {
          347         case VOID:
          348                 funtp->n.elem = 1;
          349                 if (dcl->sclass)
          350                         errorp("void as unique parameter may not be qualified");
          351                 return NULL;
          352         case ARY:
          353                 tp = mktype(tp->type, PTR, 0, NULL);
          354                 break;
          355         case FTN:
          356                 errorp("incorrect function type for a function parameter");
          357                 return NULL;
          358         }
          359         if (!empty(sym, tp, 1)) {
          360                 int isdcl = sym->flags&SDECLARED, isk_r = funtp->prop & TK_R;
          361                 if (isdcl && !isk_r) {
          362                         errorp("redefinition of parameter '%s'", name);
          363                         return NULL;
          364                 }
          365                 if (!isdcl && isk_r) {
          366                         errorp("declaration for parameter '%s' but no such parameter",
          367                                sym->name);
          368                         return NULL;
          369                 }
          370                 if (strcmp(name, "__func__") == 0)
          371                         errorp("__func__ is a reserved variable name");
          372                 sym->flags |= SDECLARED;
          373         }
          374 
          375         sym->type = tp;
          376         sym->flags &= ~(SAUTO|SREGISTER);
          377         sym->flags |= flags;
          378         return sym;
          379 }
          380 
          381 static Symbol *dodcl(int rep,
          382                      Symbol *(*fun)(struct decl *),
          383                      unsigned ns,
          384                      Type *type);
          385 
          386 static int
          387 krpars(struct declarators *dp)
          388 {
          389         Symbol *sym;
          390         int toomany = 0;
          391         unsigned npars = 0;
          392 
          393         do {
          394                 sym = yylval.sym;
          395                 expect(IDEN);
          396                 sym->flags |= SAUTO;
          397                 if ((sym = install(NS_IDEN, sym)) == NULL) {
          398                         errorp("redefinition of parameter '%s'",
          399                                yylval.sym->name);
          400                         continue;
          401                 }
          402                 if (npars < NR_FUNPARAM) {
          403                         ++npars;
          404                         *dp->pars++ = sym;
          405                         continue;
          406                 }
          407                 toomany = 1;
          408         } while (accept(','));
          409 
          410         return toomany;
          411 }
          412 
          413 static unsigned
          414 krfun(struct declarators *dp)
          415 {
          416         int toomany = 0;
          417 
          418         if (yytoken != ')')
          419                 toomany = krpars(dp);
          420 
          421         if (dp->nr_types == NR_DCL_TYP) {
          422                 toomany = 1;
          423         } else {
          424                 ++dp->nr_types;
          425                 *dp->tpars++ = ellipsistype;
          426         }
          427 
          428         if (toomany)
          429                 errorp("too many parameters in function definition");
          430         return 1;
          431 }
          432 
          433 static unsigned
          434 ansifun(struct declarators *dp)
          435 {
          436         Symbol *sym;
          437         unsigned npars, ntype, toomany, distoomany, voidpar;
          438         Type type, *tp;
          439 
          440         type.n.elem = 0;
          441         type.prop = 0;
          442         npars = ntype = toomany = distoomany = voidpar = 0;
          443 
          444         do {
          445                 if (accept(ELLIPSIS)) {
          446                         if (ntype < 1)
          447                                 errorp("a named argument is requiered before '...'");
          448                         if (yytoken != ')')
          449                                 errorp("... must be the last parameter");
          450                         sym = NULL;
          451                         tp = ellipsistype;
          452                 } else if ((sym = dodcl(NOREP, parameter, NS_IDEN, &type)) == NULL) {
          453                         voidpar = 1;
          454                         sym = NULL;
          455                         tp = NULL;
          456                 } else {
          457                         tp = sym->type;
          458                 }
          459 
          460                 if (sym) {
          461                         if (npars == NR_FUNPARAM) {
          462                                 toomany = 1;
          463                         } else {
          464                                 npars++;
          465                                 *dp->pars++ = sym;
          466                         }
          467                 }
          468 
          469                 if (tp) {
          470                         if (dp->nr_types == NR_DCL_TYP) {
          471                                 toomany = 1;
          472                         } else {
          473                                 ntype++;
          474                                 dp->nr_types++;
          475                                 *dp->tpars++ = tp;
          476                         }
          477                 }
          478 
          479         } while (accept(','));
          480 
          481         if (toomany == 1)
          482                 errorp("too many parameters in function definition");
          483         if (voidpar && ntype > 0)
          484                 errorp("'void' must be the only parameter");
          485         return ntype;
          486 }
          487 
          488 static int
          489 isfunbody(int tok)
          490 {
          491         switch (tok) {
          492         case '{':
          493         case TYPE:
          494         case SCLASS:
          495         case TYPEIDEN:
          496                 return 1;
          497         default:
          498                 return 0;
          499         }
          500 }
          501 
          502 static int
          503 funbody(Symbol *sym, Symbol *pars[])
          504 {
          505         Type *tp;
          506         Symbol **bp, *p;
          507         Symbol *emptypars[] = {NULL};
          508 
          509         if (!sym)
          510                 return 0;
          511 
          512         tp = sym->type;
          513         if (tp->op != FTN)
          514                 return 0;
          515         if (!isfunbody(yytoken) || sym->ns != NS_IDEN) {
          516                 emit(ODECL, sym);
          517                 endfundcl(tp, pars);
          518                 return  0;
          519         }
          520 
          521         if (curctx < PARAMCTX) {
          522                 assert(!pars);
          523                 errorp("typedef'ed function type cannot be instantiated");
          524                 curctx = PARAMCTX;
          525                 pars = emptypars;
          526         }
          527 
          528         if (curctx != PARAMCTX)
          529                 error("nested function declaration");
          530 
          531         tp->prop |= TFUNDEF;
          532         curfun = sym;
          533         if (tp->prop & TK_R) {
          534                 while (yytoken != '{') {
          535                         dodcl(REP, parameter, NS_IDEN, sym->type);
          536                         expect(';');
          537                 }
          538                 for (bp = pars; p = *bp; ++bp) {
          539                         if (p->type == NULL) {
          540                                 warn("type of '%s' defaults to int", p->name);
          541                                 p->type = inttype;
          542                         }
          543                 }
          544         }
          545         if (sym->flags & STYPEDEF)
          546                 errorp("function definition declared 'typedef'");
          547         if (sym->flags & SDEFINED)
          548                 errorp("redefinition of '%s'", sym->name);
          549         if (sym->flags & SEXTERN) {
          550                 sym->flags &= ~SEXTERN;
          551                 sym->flags |= SGLOBAL;
          552         }
          553         sym->flags |= SDEFINED;
          554         sym->flags &= ~SEMITTED;
          555         sym->u.pars = pars;
          556         emit(OFUN, sym);
          557         compound(NULL, NULL, NULL);
          558         emit(OEFUN, NULL);
          559         popctx();
          560         flushtypes();
          561         curfun = NULL;
          562 
          563         /*
          564          * A function declaration without arguments is a k&r function,
          565          * but when it is a definition is a function with 0 arguments
          566          */
          567         if ((tp->prop & TK_R) && *pars == NULL) {
          568                 tp = mktype(tp->type, FTN, 0, NULL);
          569                 tp->prop |= TFUNDEF;
          570                 sym->type = tp;
          571         }
          572 
          573         return 1;
          574 }
          575 
          576 static void
          577 fundcl(struct declarators *dp)
          578 {
          579         Type **types = dp->tpars;
          580         unsigned ntypes, typefun;
          581         Symbol **pars = dp->pars;
          582         unsigned (*fun)(struct declarators *);
          583 
          584         pushctx();
          585         expect('(');
          586         if (yytoken == ')' || yytoken == IDEN) {
          587                 typefun = KRFTN;
          588                 fun = krfun;
          589         } else {
          590                 typefun = FTN;
          591                 fun = ansifun;
          592         }
          593         ntypes = (*fun)(dp);
          594         *dp->pars++= NULL;
          595         expect(')');
          596 
          597         push(dp, typefun, ntypes, types, pars);
          598 }
          599 
          600 static void declarator(struct declarators *dp);
          601 
          602 static void
          603 directdcl(struct declarators *dp)
          604 {
          605         Symbol *p, *sym;
          606         static int nested;
          607 
          608         if (accept('(')) {
          609                 if (nested == NR_SUBTYPE)
          610                         error("too many declarators nested by parentheses");
          611                 ++nested;
          612                 declarator(dp);
          613                 --nested;
          614                 expect(')');
          615         } else {
          616                 if (yytoken == IDEN || yytoken == TYPEIDEN) {
          617                         sym = yylval.sym;
          618                         if (p = install(dp->ns, sym)) {
          619                                 sym = p;
          620                                 sym->flags &= ~SDECLARED;
          621                         }
          622                         next();
          623                 } else {
          624                         sym = newsym(dp->ns, NULL);
          625                 }
          626                 push(dp, IDEN, sym);
          627         }
          628 
          629         for (;;) {
          630                 switch (yytoken) {
          631                 case '(':  fundcl(dp); break;
          632                 case '[':  arydcl(dp); break;
          633                 default:   return;
          634                 }
          635         }
          636 }
          637 
          638 static void
          639 declarator(struct declarators *dp)
          640 {
          641         unsigned  n;
          642 
          643         for (n = 0; accept('*'); ++n) {
          644                 while (accept(TQUALIFIER))
          645                         ;
          646         }
          647 
          648         directdcl(dp);
          649 
          650         while (n--)
          651                 push(dp, PTR);
          652 }
          653 
          654 static Type *structdcl(void), *enumdcl(void);
          655 
          656 static Type *
          657 specifier(int *sclass, int *qualifier)
          658 {
          659         Type *tp = NULL;
          660         unsigned spec, qlf, sign, type, cls, size;
          661 
          662         spec = qlf = sign = type = cls = size = 0;
          663 
          664         for (;;) {
          665                 unsigned *p = NULL;
          666                 Type *(*dcl)(void) = NULL;
          667 
          668                 switch (yytoken) {
          669                 case SCLASS:
          670                         p = &cls;
          671                         break;
          672                 case TQUALIFIER:
          673                         qlf |= yylval.token;
          674                         next();
          675                         continue;
          676                 case TYPEIDEN:
          677                         if (type)
          678                                 goto return_type;
          679                         tp = yylval.sym->type;
          680                         p = &type;
          681                         break;
          682                 case TYPE:
          683                         switch (yylval.token) {
          684                         case ENUM:
          685                                 dcl = enumdcl;
          686                                 p = &type;
          687                                 break;
          688                         case STRUCT:
          689                         case UNION:
          690                                 dcl = structdcl;
          691                                 p = &type;
          692                                 break;
          693                         case VA_LIST:
          694                         case VOID:
          695                         case BOOL:
          696                         case CHAR:
          697                         case INT:
          698                         case FLOAT:
          699                         case DOUBLE:
          700                                 p = &type;
          701                                 break;
          702                         case SIGNED:
          703                         case UNSIGNED:
          704                                 p = &sign;
          705                                 break;
          706                         case LONG:
          707                                 if (size == LONG) {
          708                                         yylval.token = LLONG;
          709                                         size = 0;
          710                                 }
          711                         case SHORT:
          712                                 p = &size;
          713                                 break;
          714                         }
          715                         break;
          716                 default:
          717                         goto return_type;
          718                 }
          719                 if (*p)
          720                         errorp("invalid type specification");
          721                 *p = yylval.token;
          722                 if (dcl) {
          723                         if (size || sign)
          724                                 errorp("invalid type specification");
          725                         tp = (*dcl)();
          726                         goto return_type;
          727                 } else {
          728                         next();
          729                 }
          730                 spec = 1;
          731         }
          732 
          733 return_type:
          734         *sclass = cls;
          735         *qualifier = qlf;
          736         if (!tp) {
          737                 if (spec) {
          738                         tp = ctype(type, sign, size);
          739                 } else {
          740                         if (curctx != GLOBALCTX)
          741                                 unexpected();
          742                         warn("type defaults to 'int' in declaration");
          743                         tp = inttype;
          744                 }
          745         }
          746         return tp;
          747 }
          748 
          749 static Symbol *
          750 newtag(void)
          751 {
          752         Symbol *sym;
          753         int ns, op, tag = yylval.token;
          754         static int tpns = NS_STRUCTS;
          755 
          756         ns = namespace;
          757         namespace = NS_TAG;
          758         next();
          759         namespace = ns;
          760 
          761         switch (yytoken) {
          762         case IDEN:
          763         case TYPEIDEN:
          764                 sym = yylval.sym;
          765                 if ((sym->flags & SDECLARED) == 0)
          766                         install(NS_TAG, yylval.sym);
          767                 next();
          768                 break;
          769         default:
          770                 sym = newsym(NS_TAG, NULL);
          771                 break;
          772         }
          773         if (!sym->type) {
          774                 Type *tp;
          775 
          776                 if (tpns == INT_MAX)
          777                         error("too many tags declared");
          778                 tp = mktype(NULL, tag, 0, NULL);
          779                 tp->ns = tpns++;
          780                 sym->type = tp;
          781                 tp->tag = sym;
          782                 DBG("DECL: declared tag '%s' with ns = %d\n",
          783                     (sym->name) ? sym->name : "anonymous", tp->ns);
          784         }
          785 
          786         if ((op = sym->type->op) != tag &&  op != INT)
          787                 error("'%s' defined as wrong kind of tag", sym->name);
          788         return sym;
          789 }
          790 
          791 static void fieldlist(Type *tp);
          792 
          793 static Type *
          794 structdcl(void)
          795 {
          796         Symbol *sym;
          797         Type *tp;
          798         static int nested;
          799         int ns;
          800 
          801         sym = newtag();
          802         tp = sym->type;
          803 
          804         if (!accept('{'))
          805                 return tp;
          806 
          807         ns = namespace;
          808         namespace = tp->ns;
          809 
          810         if (tp->prop & TDEFINED && sym->ctx == curctx)
          811                 error("redefinition of struct/union '%s'", sym->name);
          812 
          813         if (nested == NR_STRUCT_LEVEL)
          814                 error("too many levels of nested structure or union definitions");
          815 
          816         ++nested;
          817         do fieldlist(tp); while (yytoken != '}');
          818         --nested;
          819 
          820         deftype(tp);
          821         namespace = ns;
          822         expect('}');
          823         return tp;
          824 }
          825 
          826 static Type *
          827 enumdcl(void)
          828 {
          829         Type *tp;
          830         Symbol *sym, *tagsym;
          831         int ns, val, toomany;
          832         unsigned nctes;
          833 
          834         ns = namespace;
          835         tagsym = newtag();
          836         tp = tagsym->type;
          837 
          838         namespace = NS_IDEN;
          839         if (!accept('{')) {
          840                 namespace = ns;
          841                 return tp;
          842         }
          843         if (tp->prop & TDEFINED)
          844                 errorp("redefinition of enumeration '%s'", tagsym->name);
          845         deftype(tp);
          846 
          847         /* TODO: check incorrect values in val */
          848         for (nctes = val = 0; yytoken != '}'; ++nctes, ++val) {
          849                 if (yytoken != IDEN)
          850                         unexpected();
          851                 sym = yylval.sym;
          852                 next();
          853                 if (nctes == NR_ENUM_CTES && !toomany) {
          854                         errorp("too many enum constants in a single enum");
          855                         toomany = 1;
          856                 }
          857                 if (accept('=')) {
          858                         Node *np = constexpr();
          859 
          860                         if (np == NULL)
          861                                 errorp("invalid enumeration value");
          862                         else
          863                                 val = np->sym->u.i;
          864                         freetree(np);
          865                 }
          866                 if ((sym = install(NS_IDEN, sym)) == NULL) {
          867                         errorp("'%s' redeclared as different kind of symbol",
          868                                yytext);
          869                 } else {
          870                         sym->u.i = val;
          871                         sym->flags |= SCONSTANT;
          872                         sym->type = inttype;
          873                 }
          874                 if (!accept(','))
          875                         break;
          876         }
          877         namespace = ns;
          878         expect('}');
          879         return tp;
          880 }
          881 
          882 static Symbol *
          883 type(struct decl *dcl)
          884 {
          885         Symbol *sym = dcl->sym;
          886 
          887         if (dcl->sclass)
          888                 error("class storage in type name");
          889         if (sym->name)
          890                 error("unexpected identifier in type name");
          891         sym->type = dcl->type;
          892 
          893         return sym;
          894 }
          895 
          896 static Symbol *
          897 field(struct decl *dcl)
          898 {
          899         static char *anon = "<anonymous>";
          900         Symbol *sym = dcl->sym;
          901         char *name = (sym->name) ? sym->name : anon;
          902         Type *structp = dcl->parent, *tp = dcl->type;
          903         long long n = structp->n.elem;
          904 
          905         if (accept(':')) {
          906                 Node *np;
          907                 long long n;
          908 
          909                 if ((np = constexpr()) == NULL) {
          910                         unexpected();
          911                         n = 0;
          912                 } else {
          913                         n = np->sym->u.i;
          914                         freetree(np);
          915                 }
          916                 if (n == 0 && name != anon)
          917                         errorp("zero width for bit-field '%s'", name);
          918                 if (tp != booltype && tp != inttype && tp != uinttype)
          919                         errorp("bit-field '%s' has invalid type", name);
          920                 if (n < 0)
          921                         errorp("negative width in bit-field '%s'", name);
          922                 else if (n > tp->size*8)
          923                         errorp("width of '%s' exceeds its type", name);
          924         } else if (empty(sym, tp, 0)) {
          925                 return sym;
          926         }
          927 
          928         if (sym->flags & SDECLARED) {
          929                 errorp("duplicated member '%s'", name);
          930                 return sym;
          931         }
          932 
          933         if ((tp->prop & TDEFINED) == 0) {
          934                 if (tp->op == ARY && tp->n.elem == 0) {
          935                         if (n == 0)
          936                                 errorp("flexible array member in a struct with no named members");
          937                         if (ahead() != '}')
          938                                 errorp("flexible array member not at end of struct");
          939                 } else {
          940                         errorp("field '%s' has incomplete type", name);
          941                         tp = inttype;
          942                 }
          943         }
          944         if (tp->op == FTN) {
          945                 errorp("field '%s' declared as a function", name);
          946                 tp = inttype;
          947         }
          948         if (dcl->sclass)
          949                 errorp("storage class in struct/union field '%s'", name);
          950 
          951         sym->type = tp;
          952         sym->flags |= SFIELD|SDECLARED;
          953 
          954         if (n == NR_FIELDS) {
          955                 errorp("too many fields in struct/union");
          956                 return sym;
          957         }
          958 
          959         DBG("DECL: New field '%s' in namespace %d\n", name, structp->ns);
          960         structp->p.fields = xrealloc(structp->p.fields, ++n * sizeof(*sym));
          961         structp->p.fields[n-1] = sym;
          962         structp->n.elem = n;
          963 
          964         return sym;
          965 }
          966 
          967 static Symbol *
          968 dodcl(int rep, Symbol *(*fun)(struct decl *), unsigned ns, Type *parent)
          969 {
          970         Symbol *sym;
          971         Type *base;
          972         struct decl dcl;
          973         struct declarators stack;
          974 
          975         dcl.ns = ns;
          976         dcl.parent = parent;
          977         base = specifier(&dcl.sclass, &dcl.qualifier);
          978 
          979         do {
          980                 dcl.type = base;
          981                 dcl.pars = NULL;
          982                 stack.nr_types = stack.nr = 0;
          983                 stack.tpars = dcl.buftpars;
          984                 stack.pars = dcl.bufpars;
          985                 stack.dcl = &dcl;
          986                 stack.ns = ns;
          987 
          988                 declarator(&stack);
          989 
          990                 while (pop(&stack, &dcl))
          991                         ;
          992                 sym = (*fun)(&dcl);
          993                 if (funbody(sym, dcl.pars))
          994                         return sym;
          995         } while (rep && accept(','));
          996 
          997         return sym;
          998 }
          999 
         1000 void
         1001 decl(void)
         1002 {
         1003         Symbol *sym;
         1004 
         1005         if (accept(';'))
         1006                 return;
         1007 
         1008         sym = dodcl(REP, identifier, NS_IDEN, NULL);
         1009         if ((sym->type->prop & TFUNDEF) == 0)
         1010                 expect(';');
         1011 }
         1012 
         1013 static void
         1014 fieldlist(Type *tp)
         1015 {
         1016         if (yytoken != ';')
         1017                 dodcl(REP, field, tp->ns, tp);
         1018         expect(';');
         1019 }
         1020 
         1021 Type *
         1022 typename(void)
         1023 {
         1024         return dodcl(NOREP, type, NS_DUMMY, NULL)->type;
         1025 }