ref: 5707eb558192a44df20f3da9dea2f81c14453572
parent: 1c925d70a8145ed26506926dc92c1afa4c92fb11
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Sat Aug 8 18:51:34 EDT 2015
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).
--- a/cc1/decl.c
+++ b/cc1/decl.c
@@ -140,11 +140,8 @@
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 @@
}
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 @@
}
}
- sym->u.pars = pars;
+ if ((name = sym->name) == NULL) {+ sym->type = tp;
+ } else {+ short flags;
- /* TODO: deal with external array declarations of [] */
- if (!tp->defined && sym->name)
- error("declared variable '%s' of incomplete type", sym->name);- sym->type = tp;
+ 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);
+ }
+ }
+
return sym;
}
@@ -509,7 +520,7 @@
}
do {- sym = declarator(base, ns);
+ sym = declarator(base, ns, sclass);
tp = sym->type;
switch (sclass) {--
⑨