shithub: scc

Download patch

ref: bdb96f1671f8b8f20bffc45cfacc7fa2ee2cb49f
parent: 24df403e7e688d13b5c5c29ca5a9fa6c6b2499df
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Mon Feb 20 01:22:26 EST 2017

[cc1] Install symbols in directdcl()

Installing symbols in the call back functions of dodcl() is a
bad idea because it is too late. In the case of functions the
call back function is called after parsing the parameters,
which were inserted with a higher context than the context
where the symbol was declared.

--- a/cc1/decl.c
+++ b/cc1/decl.c
@@ -178,18 +178,17 @@
 		return NULL;
 	}
 	if (!empty(sym, tp, 1)) {
-		Symbol *p = install(NS_IDEN, sym);
-		if (!p && !(funtp->prop & TK_R)) {
+		int isdcl = sym->flags&SDECLARED, isk_r = funtp->prop & TK_R;
+		if (isdcl && !isk_r) {
 			errorp("redefinition of parameter '%s'", name);
 			return NULL;
 		}
-		if (p && (funtp->prop & TK_R)) {
+		if (!isdcl && isk_r) {
 			errorp("declaration for parameter '%s' but no such parameter",
 			       sym->name);
 			return NULL;
 		}
-		if (p)
-			sym = p;
+		sym->flags |= SDECLARED;
 	}
 
 	sym->type = tp;
@@ -307,7 +306,7 @@
 static void
 directdcl(struct declarators *dp, unsigned ns)
 {
-	Symbol *sym;
+	Symbol *p, *sym;
 	static int nested;
 
 	if (accept('(')) {
@@ -320,8 +319,10 @@
 	} else {
 		if (yytoken == IDEN || yytoken == TYPEIDEN) {
 			sym = yylval.sym;
-			if (sym->ctx != curctx)
-				sym = newsym(ns, yytext);
+			if (p = install(ns, sym)) {
+				sym = p;
+				sym->flags &= ~SDECLARED;
+			}
 			next();
 		} else {
 			sym = newsym(ns, NULL);
@@ -646,11 +647,11 @@
 	if (err)
 		return sym;
 
-	if ((sym = install(dcl->ns, sym)) == NULL)
+	if (sym->flags & SDECLARED)
 		error("duplicated member '%s'", name);
+	sym->flags |= SFIELD|SDECLARED;
 	sym->type = tp;
 
-	sym->flags |= SFIELD;
 	if (n == NR_FIELDS)
 		error("too many fields in struct/union");
 	DBG("New field '%s' in namespace %d\n", name, structp->ns);
@@ -748,7 +749,6 @@
 		errorp("declared variable '%s' of incomplete type", name);
 	}
 
-	sym = install(NS_IDEN, sym);
 	if (tp->op == FTN) {
 		if (sclass == NOSCLASS)
 			sclass = EXTERN;
@@ -758,10 +758,10 @@
 		}
 	}
 
-	if (sym == NULL) {
+	if (sym->flags & SDECLARED) {
 		sym = redcl(dcl->sym, tp, dcl->pars, sclass);
 	} else {
-		int flags = sym->flags;
+		int flags = sym->flags | SDECLARED;
 
 		sym->type = tp;
 		sym->u.pars = dcl->pars;