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