shithub: scc

Download patch

ref: 229b3952de509bb616c16159020fd22ae6d2fca3
parent: a11e8815c38046241934f13a7719c724af0cb4bb
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Sat Jan 9 16:14:35 EST 2016

Split identifier() in two functions

This function was to long and with a complex logic which made very
difficult to understand it. This patch split the function in 2
functions, creating a specific function for the case when a
symbol is redeclarated.

--- a/cc1/decl.c
+++ b/cc1/decl.c
@@ -593,13 +593,72 @@
 }
 
 static Symbol *
+redcl(Symbol *sym, Type *tp, Symbol **pars, int sclass)
+{
+	int flags;
+	char *name = sym->name;
+
+	if (!eqtype(sym->type, tp)) {
+		errorp("conflicting types for '%s'", name);
+		return sym;
+	}
+
+	if (sym->token == TYPEIDEN && sclass != TYPEDEF ||
+	    sym->token != TYPEIDEN && sclass == TYPEDEF) {
+		goto redeclaration;
+	}
+	if (curctx != GLOBALCTX && tp->op != FTN) {
+		/* is it the redeclaration of a local variable? */
+		if ((sym->flags & ISEXTERN) && sclass == EXTERN)
+			return sym;
+		goto redeclaration;
+	}
+
+	sym->u.pars = pars;
+
+	flags = sym->flags;
+	switch (sclass) {
+	case REGISTER:
+	case AUTO:
+		bad_storage(tp, name);
+		break;
+	case NOSCLASS:
+		if ((flags & ISPRIVATE) == 0) {
+			flags &= ~ISEXTERN;
+			flags |= ISGLOBAL;
+			break;
+		}
+		errorp("non-static declaration of '%s' follows static declaration",
+		       name);
+		break;
+	case TYPEDEF:
+	case EXTERN:
+		break;
+	case STATIC:
+		if ((flags & (ISGLOBAL|ISEXTERN)) == 0) {
+			flags |= ISPRIVATE;
+			break;
+		}
+		errorp("static declaration of '%s' follows non-static declaration",
+		       name);
+		break;
+	}
+	sym->flags = flags;
+
+	return sym;
+
+redeclaration:
+	errorp("redeclaration of '%s'", name);
+	return sym;
+}
+
+static Symbol *
 identifier(struct decl *dcl)
 {
 	Symbol *sym = dcl->sym;
 	Type *tp = dcl->type;
-	char *name = sym->name;
-	short flags;
 	int sclass = dcl->sclass;
+	char *name = sym->name;
 
 	if (empty(sym, tp))
 		return sym;
@@ -608,7 +667,9 @@
 	if (!tp->defined && sclass != EXTERN && sclass != TYPEDEF)
 		errorp("declared variable '%s' of incomplete type", name);
 
-	if (tp->op == FTN) {
+	if (tp->op != FTN) {
+		sym = install(NS_IDEN, sym);
+	} else {
 		if (sclass == NOSCLASS)
 			sclass = EXTERN;
 		/*
@@ -622,57 +683,15 @@
 		++curctx;
 		if (!strcmp(name, "main") && tp->type != inttype)
 			errorp("please contact __20h__ on irc.oftc.net (#suckless) via IRC");
-	} else {
-		sym = install(NS_IDEN, sym);
 	}
 
 	if (sym == NULL) {
-		sym = dcl->sym;
-		if (!eqtype(sym->type, tp))
-			error("conflicting types for '%s'", name);
-		if (sym->token == TYPEIDEN && sclass != TYPEDEF ||
-		    sym->token != TYPEIDEN && sclass == TYPEDEF)
-				goto redeclaration;
-
-		if (curctx != GLOBALCTX && tp->op != FTN) {
-			if (!(sym->flags & ISEXTERN) || sclass != EXTERN)
-				goto redeclaration;
-		} else {
-			sym->u.pars = dcl->pars;
-			flags = sym->flags;
-
-			switch (sclass) {
-			case REGISTER:
-			case AUTO:
-				bad_storage(tp, name);
-				break;
-			case NOSCLASS:
-				if ((flags & ISPRIVATE) == 0) {
-					flags &= ~ISEXTERN;
-					flags |= ISGLOBAL;
-					break;
-				}
-				errorp("non-static declaration of '%s' follows static declaration",
-				       name);
-				break;
-			case TYPEDEF:
-			case EXTERN:
-				break;
-			case STATIC:
-				if ((flags & (ISGLOBAL|ISEXTERN)) == 0) {
-					flags |= ISPRIVATE;
-					break;
-				}
-				errorp("static declaration of '%s' follows non-static declaration",
-				       name);
-				break;
-			}
-		}
-		sym->flags = flags;
+		sym = redcl(dcl->sym, tp, dcl->pars, sclass);
 	} else {
+		short flags = sym->flags;
+
 		sym->type = tp;
 		sym->u.pars = dcl->pars;
-		flags = sym->flags;
 
 		switch (sclass) {
 		case REGISTER:
@@ -704,10 +723,6 @@
 		emit(ODECL, sym);
 	if (accept('='))
 		initializer(sym, sym->type, -1);
-	return sym;
-
-redeclaration:
-	errorp("redeclaration of '%s'", name);
 	return sym;
 }