scc

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

commit 5707eb558192a44df20f3da9dea2f81c14453572
parent 1c925d70a8145ed26506926dc92c1afa4c92fb11
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Sat,  8 Aug 2015 22:51:34 +0200

Accept declaration of external variables with incomplete type

This variables can be declared because the storage is not needed
for them (only a symbol is emited).

Diffstat:
cc1/decl.c | 35+++++++++++++++++++++++------------
1 file changed, 23 insertions(+), 12 deletions(-)

diff --git a/cc1/decl.c b/cc1/decl.c @@ -140,11 +140,8 @@ directdcl(struct dcldata *dp, unsigned ns) dp = declarator0(dp, ns); expect(')'); } else { - /* TODO: check type of the function */ - /* TODO: check function is not redefined */ if (yytoken == IDEN || yytoken == TYPEIDEN) { - if ((sym = install(ns, yylval.sym)) == NULL) - error("redeclaration of '%s'", yytext); + sym = yylval.sym; next(); } else { sym = newsym(ns); @@ -180,11 +177,12 @@ declarator0(struct dcldata *dp, unsigned ns) } static Symbol * -declarator(Type *tp, unsigned ns) +declarator(Type *tp, unsigned ns, int sclass) { struct dcldata data[NR_DECLARATORS+1]; struct dcldata *bp; - Symbol *sym, **pars = NULL; + Symbol *osym, *sym, **pars = NULL; + char *name; data[0].ndcl = 0; for (bp = declarator0(data, ns); bp-- > data; ) { @@ -201,12 +199,25 @@ declarator(Type *tp, unsigned ns) } } - sym->u.pars = pars; + if ((name = sym->name) == NULL) { + sym->type = tp; + } else { + short flags; + + if ((sym = install(ns, osym = sym)) == NULL) { + if (!eqtype(osym->type, tp)) + error("conflicting types for '%s'", name); + sym = osym; + } else { + sym->u.pars = pars; + sym->type = tp; + } + if (!tp->defined && sclass != EXTERN) { + error("declared variable '%s' of incomplete type", + name); + } + } - /* TODO: deal with external array declarations of [] */ - if (!tp->defined && sym->name) - error("declared variable '%s' of incomplete type", sym->name); - sym->type = tp; return sym; } @@ -509,7 +520,7 @@ dodcl(int rep, void (*fun)(Symbol *, int, Type *), uint8_t ns, Type *type) } do { - sym = declarator(base, ns); + sym = declarator(base, ns, sclass); tp = sym->type; switch (sclass) {