1#include <assert.h>2#include <limits.h>3#include <stdarg.h>4#include <stdlib.h>5#include <string.h>67#include <scc/cstd.h>8#include <scc/scc.h>9#include "cc1.h"1011#define NOSCLASS 01213#define NOREP 014#define REP 115#define FUNDCL 21617#define NR_DCL_TYP (NR_DECLARATORS+NR_FUNPARAM)18#define NR_DCL_SYM (NR_DECLARATORS+NR_FUNPARAM+1)1920struct 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};3637struct 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};484950static void51endfundcl(Type *tp, Symbol **pars)52{53 /*54 * If endfundcl is called from a type built from a typedef then55 * we do not have any parameters because in that case we only56 * 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");6162 /* avoid non used warnings in prototypes */63 while (*pars)64 (*pars++)->flags |= SUSED;65 popctx();66 }67}6869static void70push(struct declarators *dp, int op, ...)71{72 va_list va;73 unsigned n;74 struct declarator *p;7576 va_start(va, op);77 if ((n = dp->nr++) == NR_DECLARATORS)78 error("too many declarators");7980 p = &dp->d[n];81 p->op = op;82 p->tpars = NULL;8384 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}100101static int102pop(struct declarators *dp, struct decl *dcl)103{104 struct declarator *p;105106 if (dp->nr == 0)107 return 0;108109 p = &dp->d[--dp->nr];110 if (p->op == IDEN) {111 dcl->sym = p->sym;112 return 1;113 }114115 /*116 * We have a type derived from a function type. We don't care117 * about the parameters because they were used only in the118 * process of building a final type. Prototype arguments are119 * discarded in funbody() because the final type of the decl120 * is an actual function.121 */122 if (dcl->type->op == FTN)123 endfundcl(dcl->type, dcl->pars);124 dcl->pars = p->pars;125126 dcl->type = mktype(dcl->type, p->op, p->nelem, p->tpars);127 return 1;128}129130static void131arydcl(struct declarators *dp)132{133 Node *np = NULL;134 long long n = 0;135 int isfun, ns;136137 isfun = dp->flags & FUNDCL;138139 ns = namespace;140 namespace = NS_IDEN;141 expect('[');142143 for (;;) {144 if (yytoken == SCLASS && yylval.token == STATIC) {145 next();146 if (!isfun)147 errorp("static in non-parameter array declarator");148 continue;149 }150151 if (accept(TQUALIFIER)) {152 if (!isfun)153 errorp("type qualifiers in non-parameter array declarator");154 continue;155 }156157 break;158 }159160 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(']');173174 push(dp, ARY, n);175}176177static int178empty(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}195196static void197bad_storage(Type *tp, char *name)198{199 if (tp->op != FTN)200 errorp("incorrect storage class for file-scope declaration");201 else202 errorp("invalid storage class for function '%s'", name);203}204205static Symbol *206redcl(Symbol *sym, Type *tp, int sclass)207{208 int flags;209 char *name = sym->name;210211 if (!eqtype(sym->type, tp, EQUIV)) {212 errorp("conflicting types for '%s'", name);213 return sym;214 }215216 /* 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;219220 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 }230231 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;262263 if (!(sym->type->prop & TDEFINED) && tp->prop & TDEFINED)264 sym->type = tp;265266 return sym;267268redeclaration:269 errorp("redeclaration of '%s'", name);270 return sym;271}272273static Symbol *274identifier(struct decl *dcl)275{276 Symbol *sym = dcl->sym;277 Type *tp = dcl->type;278 int sclass = dcl->sclass;279 char *name = sym->name;280281 if (empty(sym, tp, 0))282 return sym;283284 /* 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 }290291 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 }298299 if (strcmp(name, "__func__") == 0)300 errorp("__func__ is a reserved variable name");301302 if (sym->flags & SDECLARED) {303 sym = redcl(dcl->sym, tp, sclass);304 } else {305 int flags = sym->flags | SDECLARED;306307 sym->type = tp;308309 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 else321 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 }336337 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}345346static Symbol *347parameter(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;353354 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 }368369 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 }397398 sym->type = tp;399 sym->flags &= ~(SAUTO|SREGISTER);400 sym->flags |= flags;401 return sym;402}403404static Symbol *dodcl(int rep,405 Symbol *(*fun)(struct decl *),406 unsigned ns,407 Type *type);408409static int410krpars(struct declarators *dp)411{412 Symbol *sym;413 int toomany = 0;414 unsigned npars = 0;415416 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(','));432433 return toomany;434}435436static unsigned437krfun(struct declarators *dp)438{439 int toomany = 0;440441 if (yytoken != ')')442 toomany = krpars(dp);443444 if (dp->nr_types == NR_DCL_TYP) {445 toomany = 1;446 } else {447 ++dp->nr_types;448 *dp->tpars++ = ellipsistype;449 }450451 if (toomany)452 errorp("too many parameters in function definition");453 return 1;454}455456static unsigned457ansifun(struct declarators *dp)458{459 Symbol *sym;460 unsigned npars, ntype, toomany, distoomany, voidpar;461 Type type, *tp;462463 type.n.elem = 0;464 type.prop = 0;465 npars = ntype = toomany = distoomany = voidpar = 0;466467 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 }485486 if (sym) {487 if (npars == NR_FUNPARAM) {488 toomany = 1;489 } else {490 npars++;491 *dp->pars++ = sym;492 }493 }494495 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 }504505 } while (accept(','));506507 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}513514static int515isfunbody(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}527528static int529funbody(Symbol *sym, Symbol *pars[])530{531 Type *tp;532 Symbol **bp, *p;533 Symbol *emptypars[] = {NULL};534535 if (!sym)536 return 0;537538 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 }546547 if (curctx < PARAMCTX) {548 assert(!pars);549 errorp("typedef'ed function type cannot be instantiated");550 curctx = PARAMCTX;551 pars = emptypars;552 }553554 if (curctx != PARAMCTX)555 error("nested function declaration");556557 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);584585 if (strcmp(sym->name, "main") == 0) {586 emit(ORET, NULL);587 emit(OEXPR, constnode(zero));588 }589590 emit(OEFUN, NULL);591 popctx();592 flushtypes();593 curfun = NULL;594595 /*596 * A function declaration without arguments is a k&r function,597 * but when it is a definition is a function with 0 arguments598 */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 }604605 return 1;606}607608static void609fundcl(struct declarators *dp)610{611 Type **types = dp->tpars;612 unsigned ntypes, typefun;613 Symbol **pars = dp->pars;614 unsigned (*fun)(struct declarators *);615616 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(')');628629 push(dp, typefun, ntypes, types, pars);630}631632static void declarator(struct declarators *dp);633634static void635directdcl(struct declarators *dp)636{637 Symbol *p, *sym;638 static int nested;639640 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 }660661 for (;;) {662 switch (yytoken) {663 case '(': fundcl(dp); break;664 case '[': arydcl(dp); break;665 default: return;666 }667 }668}669670static void671declarator(struct declarators *dp)672{673 unsigned n;674675 for (n = 0; accept('*'); ++n) {676 while (accept(TQUALIFIER))677 ;678 }679680 directdcl(dp);681682 while (n--)683 push(dp, PTR);684}685686static Type *structdcl(void), *enumdcl(void);687688static Type *689specifier(int *sclass, int *qualifier)690{691 Type *tp = NULL;692 unsigned spec, qlf, sign, type, cls, size;693694 spec = qlf = sign = type = cls = size = 0;695696 for (;;) {697 unsigned *p = NULL;698 Type *(*dcl)(void) = NULL;699700 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 }763764return_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}779780static Symbol *781newtag(void)782{783 Symbol *sym;784 int ns, op, tag = yylval.token;785 static int tpns = NS_STRUCTS;786787 ns = namespace;788 namespace = NS_TAG;789 next();790 namespace = ns;791792 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;806807 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 }816817 if ((op = sym->type->op) != tag && op != INT)818 error("'%s' defined as wrong kind of tag", sym->name);819 return sym;820}821822static void fieldlist(Type *tp);823824static Type *825structdcl(void)826{827 Symbol *sym;828 Type *tp;829 static int nested;830 int ns;831832 sym = newtag();833 tp = sym->type;834835 if (!accept('{')) {836 if (sym->name == NULL)837 unexpected();838 return tp;839 }840841 ns = namespace;842 namespace = tp->ns;843844 if (tp->prop & TDEFINED && sym->ctx == curctx)845 error("redefinition of struct/union '%s'", sym->name);846847 if (nested == NR_STRUCT_LEVEL)848 error("too many levels of nested structure or union definitions");849850 ++nested;851 do fieldlist(tp); while (yytoken != '}');852 --nested;853854 deftype(tp);855 namespace = ns;856 expect('}');857 return tp;858}859860static Type *861enumdcl(void)862{863 Type *tp;864 Symbol *sym, *tagsym;865 int ns, val, toomany;866 unsigned nctes;867868 ns = namespace;869 tagsym = newtag();870 tp = tagsym->type;871872 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);882883 /* 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();895896 if (np == NULL)897 errorp("invalid enumeration value");898 else899 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}917918static Symbol *919type(struct decl *dcl)920{921 Symbol *sym = dcl->sym;922923 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;928929 return sym;930}931932static Symbol *933field(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;940941 if (accept(':')) {942 Node *np;943 long long n;944945 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 }963964 if (sym->flags & SDECLARED) {965 errorp("duplicated member '%s'", name);966 return sym;967 }968969 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);986987 sym->type = tp;988 sym->flags |= SFIELD|SDECLARED;989990 if (n == NR_FIELDS) {991 errorp("too many fields in struct/union");992 return sym;993 }994995 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;9991000 return sym;1001}10021003static Symbol *1004dodcl(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;10111012 dcl.ns = ns;1013 dcl.parent = parent;1014 base = specifier(&dcl.sclass, &dcl.qualifier);10151016 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;10251026 declarator(&stack);10271028 while (pop(&stack, &dcl))1029 ;1030 sym = (*fun)(&dcl);1031 if (funbody(sym, dcl.pars))1032 return sym;1033 } while (rep && accept(','));10341035 return sym;1036}10371038void1039decl(void)1040{1041 Symbol *sym;10421043 if (accept(';'))1044 return;10451046 sym = dodcl(REP, identifier, NS_IDEN, NULL);1047 if ((sym->type->prop & TFUNDEF) == 0)1048 expect(';');1049}10501051static void1052fieldlist(Type *tp)1053{1054 if (yytoken != ';')1055 dodcl(REP, field, tp->ns, tp);1056 expect(';');1057}10581059Type *1060typename(void)1061{1062 return dodcl(NOREP, type, NS_DUMMY, NULL)->type;1063}