commit 5707eb558192a44df20f3da9dea2f81c14453572
Author:     Roberto E. Vargas Caballero <k...@shike2.com>
AuthorDate: Sat Aug 8 22:51:34 2015 +0200
Commit:     Roberto E. Vargas Caballero <k...@shike2.com>
CommitDate: Sat Aug 8 22:51:34 2015 +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).

diff --git a/cc1/decl.c b/cc1/decl.c
index 58f0458..e783615 100644
--- 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) {

Reply via email to