scc

Simple C99 Compiler
Log | Files | Refs | README | LICENSE

decl.c (16626B)


      1 /* See LICENSE file for copyright and license details. */
      2 #include <setjmp.h>
      3 #include <stdarg.h>
      4 #include <stdio.h>
      5 #include <stdlib.h>
      6 #include <string.h>
      7 
      8 #include "../inc/sizes.h"
      9 #include "../inc/cc.h"
     10 #include "arch.h"
     11 #include "cc1.h"
     12 
     13 #define NOSCLASS  0
     14 
     15 struct declarators {
     16 	unsigned char nr;
     17 	struct declarator {
     18 		unsigned char op;
     19 		TINT  nelem;
     20 		Symbol *sym;
     21 		Type **tpars;
     22 		Symbol **pars;
     23 	} d [NR_DECLARATORS];
     24 };
     25 
     26 struct decl {
     27 	unsigned ns;
     28 	int sclass;
     29 	int qualifier;
     30 	Symbol *sym;
     31 	Symbol **pars;
     32 	Type *type;
     33 	Type *parent;
     34 };
     35 
     36 static void
     37 push(struct declarators *dp, int op, ...)
     38 {
     39 	va_list va;
     40 	unsigned n;
     41 	struct declarator *p;
     42 
     43 	va_start(va, op);
     44 	if ((n = dp->nr++) == NR_DECLARATORS)
     45 		error("too many declarators");
     46 
     47 	p = &dp->d[n];
     48 	p->op = op;
     49 	p->tpars = NULL;
     50 
     51 	switch (op) {
     52 	case ARY:
     53 		p->nelem = va_arg(va, TINT);
     54 		break;
     55 	case KRFTN:
     56 	case FTN:
     57 		p->nelem = va_arg(va, TINT);
     58 		p->tpars = va_arg(va, Type **);
     59 		p->pars = va_arg(va, Symbol **);
     60 		break;
     61 	case IDEN:
     62 		p->sym = va_arg(va, Symbol *);
     63 		break;
     64 	}
     65 	va_end(va);
     66 }
     67 
     68 static int
     69 pop(struct declarators *dp, struct decl *dcl)
     70 {
     71 	struct declarator *p;
     72 
     73 	if (dp->nr == 0)
     74 		return 0;
     75 
     76 	p = &dp->d[--dp->nr];
     77 	if (p->op == IDEN) {
     78 		dcl->sym = p->sym;
     79 		return 1;
     80 	}
     81 	if (dcl->type->op == FTN) {
     82 		/*
     83 		 * constructor applied to a
     84 		 * function. We  don't need
     85 		 * the parameter symbols anymore.
     86 		 */
     87 		free(dcl->pars);
     88 		popctx();
     89 		dcl->pars = NULL;
     90 	}
     91 	if (p->op == FTN || p->op == KRFTN)
     92 		dcl->pars = p->pars;
     93 	dcl->type = mktype(dcl->type, p->op, p->nelem, p->tpars);
     94 	return 1;
     95 }
     96 
     97 static void
     98 arydcl(struct declarators *dp)
     99 {
    100 	Node *np = NULL;
    101 	TINT n = 0;
    102 
    103 	expect('[');
    104 	if (yytoken != ']') {
    105 		if ((np = iconstexpr()) == NULL) {
    106 			errorp("invalid storage size");
    107 		} else {
    108 			if ((n = np->sym->u.i) <= 0) {
    109 				errorp("array size is not a positive number");
    110 				n = 1;
    111 			}
    112 			freetree(np);
    113 		}
    114 	}
    115 	expect(']');
    116 
    117 	push(dp, ARY, n);
    118 }
    119 
    120 static int
    121 empty(Symbol *sym, Type *tp)
    122 {
    123 	if (!sym->name) {
    124 		sym->type = tp;
    125 		switch (tp->op) {
    126 		default:
    127 			warn("empty declaration");
    128 		case STRUCT:
    129 		case UNION:
    130 		case ENUM:
    131 			return 1;
    132 		}
    133 	}
    134 	return 0;
    135 }
    136 
    137 static Symbol *
    138 parameter(struct decl *dcl)
    139 {
    140 	Symbol *sym = dcl->sym;
    141 	Type *funtp = dcl->parent, *tp = dcl->type;
    142 	TINT n = funtp->n.elem;
    143 	char *name = sym->name;
    144 	int flags;
    145 
    146 	flags = 0;
    147 	switch (dcl->sclass) {
    148 	case STATIC:
    149 	case EXTERN:
    150 	case AUTO:
    151 		errorp("bad storage class in function parameter");
    152 		break;
    153 	case REGISTER:
    154 		flags |= SREGISTER;
    155 		break;
    156 	case NOSCLASS:
    157 		flags |= SAUTO;
    158 		break;
    159 	}
    160 
    161 	switch (tp->op) {
    162 	case VOID:
    163 		if (n != 0 || (funtp->prop & TK_R)) {
    164 			errorp("incorrect void parameter");
    165 			return NULL;
    166 		}
    167 		funtp->n.elem = -1;
    168 		if (dcl->sclass)
    169 			errorp("void as unique parameter may not be qualified");
    170 		return NULL;
    171 	case ARY:
    172 		tp = mktype(tp->type, PTR, 0, NULL);
    173 		break;
    174 	case FTN:
    175 		errorp("incorrect function type for a function parameter");
    176 		return NULL;
    177 	}
    178 	if (!empty(sym, tp)) {
    179 		Symbol *p = install(NS_IDEN, sym);
    180 		if (!p && !(funtp->prop & TK_R)) {
    181 			errorp("redefinition of parameter '%s'", name);
    182 			return NULL;
    183 		}
    184 		if (p && (funtp->prop & TK_R)) {
    185 			errorp("declaration for parameter ā€˜%sā€™ but no such parameter",
    186 			       sym->name);
    187 			return NULL;
    188 		}
    189 		if (p)
    190 			sym = p;
    191 	}
    192 
    193 	sym->type = tp;
    194 	sym->flags &= ~(SAUTO|SREGISTER);
    195 	sym->flags |= flags;
    196 	return sym;
    197 }
    198 
    199 static Symbol *dodcl(int rep,
    200                      Symbol *(*fun)(struct decl *),
    201                      unsigned ns,
    202                      Type *type);
    203 
    204 static void
    205 krfun(Type *tp, Type *types[], Symbol *syms[], int *ntypes, int *nsyms)
    206 {
    207 	int n = 0;
    208 	Symbol *sym;
    209 	int toomany = 0;
    210 
    211 	if (yytoken != ')') {
    212 		do {
    213 			sym = yylval.sym;
    214 			expect(IDEN);
    215 			sym->type = inttype;
    216 			sym->flags |= SAUTO;
    217 			if ((sym = install(NS_IDEN, sym)) == NULL) {
    218 				errorp("redefinition of parameter '%s'",
    219 				       yylval.sym->name);
    220 				continue;
    221 			}
    222 			if (n < NR_FUNPARAM) {
    223 				++n;
    224 				*syms++ = sym;
    225 				continue;
    226 			}
    227 			if (!toomany)
    228 				errorp("too much parameters in function definition");
    229 			toomany = 1;
    230 		} while (accept(','));
    231 	}
    232 
    233 	*nsyms = n;
    234 	*ntypes = 1;
    235 	types[0] = ellipsistype;
    236 }
    237 
    238 static void
    239 ansifun(Type *tp, Type *types[], Symbol *syms[], int *ntypes, int *nsyms)
    240 {
    241 	int n = 0;
    242 	Symbol *sym;
    243 	int toomany = 0, toovoid = 0;
    244 
    245 	do {
    246 		if (n == -1 && !toovoid) {
    247 			errorp("'void' must be the only parameter");
    248 			toovoid = 1;
    249 		}
    250 		if (accept(ELLIPSIS)) {
    251 			if (n == 0)
    252 				errorp("a named argument is requiered before '...'");
    253 			++n;
    254 			*syms = NULL;
    255 			*types++ = ellipsistype;
    256 			break;
    257 		}
    258 		if ((sym = dodcl(0, parameter, NS_IDEN, tp)) == NULL)
    259 			continue;
    260 		if (tp->n.elem == -1) {
    261 			n = -1;
    262 			continue;
    263 		}
    264 		if (n < NR_FUNPARAM) {
    265 			*syms++ = sym;
    266 			*types++ = sym->type;
    267 			++n;
    268 			continue;
    269 		}
    270 		if (!toomany)
    271 			errorp("too many parameters in function definition");
    272 		toomany = 1;
    273 	} while (accept(','));
    274 
    275 	*nsyms = n;
    276 	*ntypes = n;
    277 }
    278 
    279 static void
    280 fundcl(struct declarators *dp)
    281 {
    282 	Type *types[NR_FUNPARAM], type;
    283 	Symbol *syms[NR_FUNPARAM+1], **pars;
    284 	int k_r, ntypes, nsyms;
    285 	size_t size;
    286 
    287 	pushctx();
    288 	expect('(');
    289 	type.n.elem = 0;
    290 	type.prop = 0;
    291 
    292 	k_r = (yytoken == ')' || yytoken == IDEN);
    293 	(k_r ? krfun : ansifun)(&type, types, syms, &ntypes, &nsyms);
    294 	expect(')');
    295 
    296 	type.n.elem = ntypes;
    297 	if (ntypes <= 0) {
    298 		type.p.pars = NULL;
    299 	} else {
    300 		size = ntypes * sizeof(Type *);
    301 		type.p.pars = memcpy(xmalloc(size), types, size);
    302 	}
    303 	if (nsyms <= 0) {
    304 		pars = NULL;
    305 	} else {
    306 		size = (nsyms + 1) * sizeof(Symbol *);
    307 		pars = memcpy(xmalloc(size), syms, size);
    308 		pars[nsyms] = NULL;
    309 	}
    310 	push(dp, (k_r) ? KRFTN : FTN, type.n.elem, type.p.pars, pars);
    311 }
    312 
    313 static void declarator(struct declarators *dp, unsigned ns);
    314 
    315 static void
    316 directdcl(struct declarators *dp, unsigned ns)
    317 {
    318 	Symbol *sym;
    319 	static int nested;
    320 
    321 	if (accept('(')) {
    322 		if (nested == NR_SUBTYPE)
    323 			error("too many declarators nested by parentheses");
    324 		++nested;
    325 		declarator(dp, ns);
    326 		--nested;
    327 		expect(')');
    328 	} else {
    329 		if (yytoken == IDEN || yytoken == TYPEIDEN) {
    330 			sym = yylval.sym;
    331 			next();
    332 		} else {
    333 			sym = newsym(ns);
    334 		}
    335 		push(dp, IDEN, sym);
    336 	}
    337 
    338 	for (;;) {
    339 		switch (yytoken) {
    340 		case '(':  fundcl(dp); break;
    341 		case '[':  arydcl(dp); break;
    342 		default:   return;
    343 		}
    344 	}
    345 }
    346 
    347 static void
    348 declarator(struct declarators *dp, unsigned ns)
    349 {
    350 	unsigned  n;
    351 
    352 	for (n = 0; accept('*'); ++n) {
    353 		while (accept(TQUALIFIER))
    354 			/* nothing */;
    355 	}
    356 
    357 	directdcl(dp, ns);
    358 
    359 	while (n--)
    360 		push(dp, PTR);
    361 }
    362 
    363 static Type *structdcl(void), *enumdcl(void);
    364 
    365 static Type *
    366 specifier(int *sclass, int *qualifier)
    367 {
    368 	Type *tp = NULL;
    369 	unsigned spec, qlf, sign, type, cls, size;
    370 
    371 	spec = qlf = sign = type = cls = size = 0;
    372 
    373 	for (;;) {
    374 		unsigned *p = NULL;
    375 		Type *(*dcl)(void) = NULL;
    376 
    377 		switch (yytoken) {
    378 		case SCLASS:
    379 			p = &cls;
    380 			break;
    381 		case TQUALIFIER:
    382 			qlf |= yylval.token;
    383 			next();
    384 			continue;
    385 		case TYPEIDEN:
    386 			if (type)
    387 				goto return_type;
    388 			tp = yylval.sym->type;
    389 			p = &type;
    390 			break;
    391 		case TYPE:
    392 			switch (yylval.token) {
    393 			case ENUM:
    394 				dcl = enumdcl;
    395 				p = &type;
    396 				break;
    397 			case STRUCT:
    398 			case UNION:
    399 				dcl = structdcl;
    400 				p = &type;
    401 				break;
    402 			case VOID:
    403 			case BOOL:
    404 			case CHAR:
    405 			case INT:
    406 			case FLOAT:
    407 			case DOUBLE:
    408 				p = &type;
    409 				break;
    410 			case SIGNED:
    411 			case UNSIGNED:
    412 				p = &sign;
    413 				break;
    414 			case LONG:
    415 				if (size == LONG) {
    416 					yylval.token = LLONG;
    417 					size = 0;
    418 				}
    419 			case SHORT:
    420 				p = &size;
    421 				break;
    422 			}
    423 			break;
    424 		default:
    425 			goto return_type;
    426 		}
    427 		if (*p)
    428 			errorp("invalid type specification");
    429 		*p = yylval.token;
    430 		if (dcl) {
    431 			if (size || sign)
    432 				errorp("invalid type specification");
    433 			tp = (*dcl)();
    434 			goto return_type;
    435 		} else {
    436 			next();
    437 		}
    438 		spec = 1;
    439 	}
    440 
    441 return_type:
    442 	*sclass = cls;
    443 	*qualifier = qlf;
    444 	if (!tp) {
    445 		if (spec) {
    446 			tp = ctype(type, sign, size);
    447 		} else {
    448 			if (curctx != GLOBALCTX)
    449 				unexpected();
    450 			warn("type defaults to 'int' in declaration");
    451 			tp = inttype;
    452 		}
    453 	}
    454 	return tp;
    455 }
    456 
    457 static Symbol *
    458 newtag(void)
    459 {
    460 	Symbol *sym;
    461 	int op, tag = yylval.token;
    462 	static unsigned ns = NS_STRUCTS;
    463 
    464 	namespace = NS_TAG;
    465 	next();
    466 
    467 	switch (yytoken) {
    468 	case IDEN:
    469 	case TYPEIDEN:
    470 		sym = yylval.sym;
    471 		if ((sym->flags & SDECLARED) == 0)
    472 			install(NS_TAG, yylval.sym);
    473 		namespace = NS_IDEN;
    474 		next();
    475 		break;
    476 	default:
    477 		sym = newsym(NS_TAG);
    478 		break;
    479 	}
    480 	if (!sym->type) {
    481 		Type *tp;
    482 
    483 		if (ns == NS_STRUCTS + NR_MAXSTRUCTS)
    484 			error("too many tags declared");
    485 		tp = mktype(NULL, tag, 0, NULL);
    486 		tp->ns = ns++;
    487 		sym->type = tp;
    488 		tp->tag = sym;
    489 		DBG("declared tag '%s' with ns = %d\n",
    490 		    (sym->name) ? sym->name : "anonymous", tp->ns);
    491 	}
    492 
    493 	if ((op = sym->type->op) != tag &&  op != INT)
    494 		error("'%s' defined as wrong kind of tag", sym->name);
    495 	return sym;
    496 }
    497 
    498 /* TODO: bitfields */
    499 
    500 static void fieldlist(Type *tp);
    501 
    502 static Type *
    503 structdcl(void)
    504 {
    505 	Symbol *sym;
    506 	Type *tp;
    507 	static int nested;
    508 	int ns;
    509 
    510 	ns = namespace;
    511 	sym = newtag();
    512 	tp = sym->type;
    513 	namespace = tp->ns;
    514 
    515 	if (!accept('{')) {
    516 		namespace = ns;
    517 		return tp;
    518 	}
    519 
    520 	if (tp->prop & TDEFINED)
    521 		error("redefinition of struct/union '%s'", sym->name);
    522 	tp->prop |= TDEFINED;
    523 
    524 	if (nested == NR_STRUCT_LEVEL)
    525 		error("too many levels of nested structure or union definitions");
    526 
    527 	++nested;
    528 	while (yytoken != '}') {
    529 		fieldlist(tp);
    530 	}
    531 	--nested;
    532 
    533 	typesize(tp);
    534 	namespace = ns;
    535 	expect('}');
    536 	return tp;
    537 }
    538 
    539 static Type *
    540 enumdcl(void)
    541 {
    542 	Type *tp;
    543 	Symbol *sym, *tagsym;
    544 	int ns, val, toomany;
    545 	unsigned nctes;
    546 
    547 	ns = namespace;
    548 	tagsym = newtag();
    549 	tp = tagsym->type;
    550 
    551 	if (!accept('{'))
    552 		goto restore_name;
    553 	if (tp->prop & TDEFINED)
    554 		errorp("redefinition of enumeration '%s'", tagsym->name);
    555 	tp->prop |= TDEFINED;
    556 	namespace = NS_IDEN;
    557 
    558 	/* TODO: check incorrect values in val */
    559 	for (nctes = val = 0; yytoken != '}'; ++nctes, ++val) {
    560 		if (yytoken != IDEN)
    561 			unexpected();
    562 		sym = yylval.sym;
    563 		next();
    564 		if (nctes == NR_ENUM_CTES && !toomany) {
    565 			errorp("too many enum constants in a single enum");
    566 			toomany = 1;
    567 		}
    568 		if (accept('=')) {
    569 			Node *np = iconstexpr();
    570 
    571 			if (np == NULL)
    572 				errorp("invalid enumeration value");
    573 			else
    574 				val = np->sym->u.i;
    575 			freetree(np);
    576 		}
    577 		if ((sym = install(NS_IDEN, sym)) == NULL) {
    578 			errorp("'%s' redeclared as different kind of symbol",
    579 			       yytext);
    580 		} else {
    581 			sym->u.i = val;
    582 			sym->flags |= SCONSTANT;
    583 			sym->type = inttype;
    584 		}
    585 		if (!accept(','))
    586 			break;
    587 	}
    588 	expect('}');
    589 
    590 restore_name:
    591 	namespace = ns;
    592 	return tp;
    593 }
    594 
    595 static Symbol *
    596 type(struct decl *dcl)
    597 {
    598 	Symbol *sym = dcl->sym;
    599 
    600 	if (dcl->sclass)
    601 		error("class storage in type name");
    602 	if (sym->name)
    603 		error("unexpected identifier in type name");
    604 	sym->type = dcl->type;
    605 
    606 	return sym;
    607 }
    608 
    609 static Symbol *
    610 field(struct decl *dcl)
    611 {
    612 	Symbol *sym = dcl->sym;
    613 	char *name = sym->name;
    614 	Type *structp = dcl->parent, *tp = dcl->type;
    615 	TINT n = structp->n.elem;
    616 	int err = 0;
    617 
    618 	if (empty(sym, tp))
    619 		return sym;
    620 	if (tp->op == FTN) {
    621 		errorp("invalid type in struct/union");
    622 		err = 1;
    623 	}
    624 	if (dcl->sclass) {
    625 		errorp("storage class in struct/union field");
    626 		err = 1;
    627 	}
    628 	if (!(tp->prop & TDEFINED)) {
    629 		error("field '%s' has incomplete type", name);
    630 		err = 1;
    631 	}
    632 	if (err)
    633 		return sym;
    634 
    635 	if ((sym = install(dcl->ns, sym)) == NULL)
    636 		error("duplicated member '%s'", name);
    637 	sym->type = tp;
    638 
    639 	sym->flags |= SFIELD;
    640 	if (n == NR_FIELDS)
    641 		error("too many fields in struct/union");
    642 	DBG("New field '%s' in namespace %d\n", name, structp->ns);
    643 	structp->p.fields = xrealloc(structp->p.fields, ++n * sizeof(*sym));
    644 	structp->p.fields[n-1] = sym;
    645 	structp->n.elem = n;
    646 
    647 	return sym;
    648 }
    649 
    650 static void
    651 bad_storage(Type *tp, char *name)
    652 {
    653 	if (tp->op != FTN)
    654 		errorp("incorrect storage class for file-scope declaration");
    655 	else
    656 		errorp("invalid storage class for function '%s'", name);
    657 }
    658 
    659 static Symbol *
    660 redcl(Symbol *sym, Type *tp, Symbol **pars, int sclass)
    661 {
    662 	int flags;
    663 	char *name = sym->name;
    664 
    665 	if (!eqtype(sym->type, tp)) {
    666 		errorp("conflicting types for '%s'", name);
    667 		return sym;
    668 	}
    669 
    670 	if (sym->token == TYPEIDEN && sclass != TYPEDEF ||
    671 	    sym->token != TYPEIDEN && sclass == TYPEDEF) {
    672 		goto redeclaration;
    673 	}
    674 	if (curctx != GLOBALCTX && tp->op != FTN) {
    675 		/* is it the redeclaration of a local variable? */
    676 		if ((sym->flags & SEXTERN) && sclass == EXTERN)
    677 			return sym;
    678 		goto redeclaration;
    679 	}
    680 
    681 	sym->u.pars = pars;
    682 
    683 	flags = sym->flags;
    684 	switch (sclass) {
    685 	case REGISTER:
    686 	case AUTO:
    687 		bad_storage(tp, name);
    688 		break;
    689 	case NOSCLASS:
    690 		if ((flags & SPRIVATE) == 0) {
    691 			flags &= ~SEXTERN;
    692 			flags |= SGLOBAL;
    693 			break;
    694 		}
    695 		errorp("non-static declaration of '%s' follows static declaration",
    696 		       name);
    697 		break;
    698 	case TYPEDEF:
    699 	case EXTERN:
    700 		break;
    701 	case STATIC:
    702 		if ((flags & (SGLOBAL|SEXTERN)) == 0) {
    703 			flags |= SPRIVATE;
    704 			break;
    705 		}
    706 		errorp("static declaration of '%s' follows non-static declaration",
    707 		       name);
    708 		break;
    709 	}
    710 	sym->flags = flags;
    711 
    712 	return sym;
    713 
    714 redeclaration:
    715 	errorp("redeclaration of '%s'", name);
    716 	return sym;
    717 }
    718 
    719 static Symbol *
    720 identifier(struct decl *dcl)
    721 {
    722 	Symbol *sym = dcl->sym;
    723 	Type *tp = dcl->type;
    724 	int sclass = dcl->sclass;
    725 	char *name = sym->name;
    726 
    727 	if (empty(sym, tp))
    728 		return sym;
    729 
    730 	/* TODO: Add warning about ANSI limits */
    731 	if (!(tp->prop & TDEFINED)                &&
    732 	    sclass != EXTERN && sclass != TYPEDEF &&
    733 	    !(tp->op == ARY && yytoken == '=')) {
    734 		errorp("declared variable '%s' of incomplete type", name);
    735 	}
    736 
    737 	if (tp->op != FTN) {
    738 		sym = install(NS_IDEN, sym);
    739 	} else {
    740 		if (sclass == NOSCLASS)
    741 			sclass = EXTERN;
    742 		/*
    743 		 * Ugly workaround to solve function declarations.
    744 		 * A new context is added for the parameters,
    745 		 * so at this point curctx is incremented by
    746 		 * one since sym was parsed.
    747 		 */
    748 		--curctx;
    749 		sym = install(NS_IDEN, sym);
    750 		++curctx;
    751 		if (!strcmp(name, "main") && tp->type != inttype)
    752 			errorp("please contact __20h__ on irc.oftc.net (#suckless) via IRC");
    753 	}
    754 
    755 	if (sym == NULL) {
    756 		sym = redcl(dcl->sym, tp, dcl->pars, sclass);
    757 	} else {
    758 		short flags = sym->flags;
    759 
    760 		sym->type = tp;
    761 		sym->u.pars = dcl->pars;
    762 
    763 		switch (sclass) {
    764 		case REGISTER:
    765 		case AUTO:
    766 			if (curctx != GLOBALCTX && tp->op != FTN) {
    767 				flags |= (sclass == REGISTER) ? SREGISTER : SAUTO;
    768 				break;
    769 			}
    770 			bad_storage(tp, name);
    771 		case NOSCLASS:
    772 			if (tp->op == FTN)
    773 				flags |= SEXTERN;
    774 			else
    775 				flags |= (curctx == GLOBALCTX) ? SGLOBAL : SAUTO;
    776 			break;
    777 		case EXTERN:
    778 			flags |= SEXTERN;
    779 			break;
    780 		case STATIC:
    781 			flags |= (curctx == GLOBALCTX) ? SPRIVATE : SLOCAL;
    782 			break;
    783 		case TYPEDEF:
    784 			flags |= STYPEDEF;
    785 			sym->u.token = sym->token = TYPEIDEN;
    786 			break;
    787 		}
    788 		sym->flags = flags;
    789 	}
    790 
    791 	if (accept('='))
    792 		initializer(sym, sym->type);
    793 	if (!(sym->flags & (SGLOBAL|SEXTERN)) && tp->op != FTN)
    794 		sym->flags |= SDEFINED;
    795 	if (sym->token == IDEN && sym->type->op != FTN)
    796 		emit(ODECL, sym);
    797 	return sym;
    798 }
    799 
    800 static Symbol *
    801 dodcl(int rep, Symbol *(*fun)(struct decl *), unsigned ns, Type *parent)
    802 {
    803 	Symbol *sym;
    804 	Type *base;
    805 	struct decl dcl;
    806 	struct declarators stack;
    807 
    808 	dcl.ns = ns;
    809 	dcl.parent = parent;
    810 	base = specifier(&dcl.sclass, &dcl.qualifier);
    811 
    812 	do {
    813 		stack.nr = 0;
    814 		dcl.pars = NULL;
    815 		dcl.type = base;
    816 
    817 		declarator(&stack, ns);
    818 
    819 		while (pop(&stack, &dcl))
    820 			/* nothing */;
    821 		sym = (*fun)(&dcl);
    822 	} while (rep && accept(','));
    823 
    824 	return sym;
    825 }
    826 
    827 void
    828 decl(void)
    829 {
    830 	Symbol **p, *par, *sym, *ocurfun;
    831 
    832 	if (accept(';'))
    833 		return;
    834 	sym = dodcl(1, identifier, NS_IDEN, NULL);
    835 
    836 	if (sym->type->op != FTN) {
    837 		expect(';');
    838 		return;
    839 	}
    840 
    841 	ocurfun = curfun;
    842 	curfun = sym;
    843 	/*
    844 	 * Functions only can appear at global context,
    845 	 * but due to parameter context, we have to check
    846 	 * against GLOBALCTX+1
    847 	 */
    848 	if (curctx != GLOBALCTX+1 || yytoken == ';') {
    849 		emit(ODECL, sym);
    850 		/*
    851 		 * avoid non used warnings in prototypes
    852 		 */
    853 		for (p = sym->u.pars;  p && *p; ++p)
    854 			(*p)->flags |= SUSED;
    855 		popctx();
    856 		expect(';');
    857 		free(sym->u.pars);
    858 		sym->u.pars = NULL;
    859 		curfun = ocurfun;
    860 		return;
    861 	}
    862 	if (sym->type->prop & TK_R) {
    863 		while (yytoken != '{') {
    864 			par = dodcl(1, parameter, NS_IDEN, sym->type);
    865 			expect(';');
    866 		}
    867 	}
    868 
    869 	if (sym->flags & STYPEDEF)
    870 		errorp("function definition declared 'typedef'");
    871 	if (sym->flags & SDEFINED)
    872 		errorp("redefinition of '%s'", sym->name);
    873 	if (sym->flags & SEXTERN) {
    874 		sym->flags &= ~SEXTERN;
    875 		sym->flags |= SGLOBAL;
    876 	}
    877 
    878 	sym->flags |= SDEFINED;
    879 	sym->flags &= ~SEMITTED;
    880 	emit(OFUN, sym);
    881 	compound(NULL, NULL, NULL);
    882 	emit(OEFUN, NULL);
    883 	curfun = ocurfun;
    884 }
    885 
    886 static void
    887 fieldlist(Type *tp)
    888 {
    889 	if (yytoken != ';')
    890 		dodcl(1, field, tp->ns, tp);
    891 	expect(';');
    892 }
    893 
    894 Type *
    895 typename(void)
    896 {
    897 	return dodcl(0, type, 0, NULL)->type;
    898 }