shithub: scc

Download patch

ref: 695cff844c8fb4d44a68da49758db726f47d9288
parent: 66a93a10f87bb84426e2cc1ba00bde93cdbd92e6
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Tue May 19 10:48:33 EDT 2015

Allow symbol without name in cc1

The case of the anonymous labels is common, and they were going to
the same hash position, because all of them had "" as name. It is
better don't link them in the hash when they are not going to be
searched later.

--- a/cc1/decl.c
+++ b/cc1/decl.c
@@ -115,7 +115,7 @@
 		if (yytoken == IDEN || yytoken == TYPEIDEN)
 			sym = newiden(ns);
 		else
-			sym = install("", ns);
+			sym = install(NULL, ns);
 		dp = queue(dp, IDEN, 0, sym);
 	}
 
@@ -281,7 +281,7 @@
 		next();
 		break;
 	default:
-		sym = install("", NS_TAG);
+		sym = install(NULL, NS_TAG);
 		break;
 	}
 	if (!sym->type) {
--- a/cc1/lex.c
+++ b/cc1/lex.c
@@ -246,7 +246,7 @@
 
 convert:
 	tp = ctype(INT, sign, size);
-	sym = install("", NS_IDEN);
+	sym = install(NULL, NS_IDEN);
 	sym->type = tp;
 	v = strtol(s, NULL, base);
 	if (tp == inttype)
@@ -345,7 +345,7 @@
 		error("invalid character constant");
 	++input->p;
 
-	sym = install("", NS_IDEN);
+	sym = install(NULL, NS_IDEN);
 	sym->u.i = c;
 	sym->type = inttype;
 	yylval.sym = sym;
@@ -386,7 +386,7 @@
 	}
 
 	*bp = '\0';
-	sym = install("", NS_IDEN);
+	sym = install(NULL, NS_IDEN);
 	sym->u.s = xstrdup(buf);
 	sym->type = mktype(chartype, ARY, (bp - buf) + 1, NULL);
 	yylval.sym = sym;
--- a/cc1/stmt.c
+++ b/cc1/stmt.c
@@ -72,9 +72,9 @@
 	Symbol *begin, *cond, *end;
 	Node *np;
 
-	begin = install("", NS_LABEL);
-	end = install("", NS_LABEL);
-	cond = install("", NS_LABEL);
+	begin = install(NULL, NS_LABEL);
+	end = install(NULL, NS_LABEL);
+	cond = install(NULL, NS_LABEL);
 
 	expect(WHILE);
 	np = condition();
@@ -95,9 +95,9 @@
 	Symbol *begin, *cond, *end;
 	Node *econd, *einc, *einit;
 
-	begin = install("", NS_LABEL);
-	end = install("", NS_LABEL);
-	cond = install("", NS_LABEL);
+	begin = install(NULL, NS_LABEL);
+	end = install(NULL, NS_LABEL);
+	cond = install(NULL, NS_LABEL);
 
 	expect(FOR);
 	expect('(');
@@ -127,8 +127,8 @@
 	Symbol *begin, *end;
 	Node *np;
 
-	begin = install("", NS_LABEL);
-	end = install("", NS_LABEL);
+	begin = install(NULL, NS_LABEL);
+	end = install(NULL, NS_LABEL);
 	expect(DO);
 	emit(OBLOOP, NULL);
 	emit(OLABEL, begin);
@@ -229,8 +229,8 @@
 		error("incorrect type in switch statement");
 	expect (')');
 
-	lbreak = install("", NS_LABEL);
-	lcond = install("", NS_LABEL);
+	lbreak = install(NULL, NS_LABEL);
+	lcond = install(NULL, NS_LABEL);
 	emit(OJUMP, lcond);
 	stmt(lbreak, lcont, &lcase);
 	emit(OLABEL, lcond);
@@ -263,7 +263,7 @@
 	pcase = xmalloc(sizeof(*pcase));
 	pcase->expr = np;
 	pcase->next = lswitch->head;
-	emit(OLABEL, pcase->label = install("", NS_LABEL));
+	emit(OLABEL, pcase->label = install(NULL, NS_LABEL));
 	lswitch->head = pcase;
 	++lswitch->nr;
 }
@@ -271,7 +271,7 @@
 static void
 Default(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
 {
-	Symbol *ldefault = install("", NS_LABEL);
+	Symbol *ldefault = install(NULL, NS_LABEL);
 
 	expect(DEFAULT);
 	expect(':');
@@ -285,7 +285,7 @@
 	Symbol *end, *lelse;
 	Node *np;
 
-	lelse = install("", NS_LABEL);
+	lelse = install(NULL, NS_LABEL);
 	expect(IF);
 	np = condition();
 	emit(OBRANCH, lelse);
@@ -292,7 +292,7 @@
 	emit(OEXPR, negate(np));
 	stmt(lbreak, lcont, lswitch);
 	if (accept(ELSE)) {
-		end = install("", NS_LABEL);
+		end = install(NULL, NS_LABEL);
 		emit(OJUMP, end);
 		emit(OLABEL, lelse);
 		stmt(lbreak, lcont, lswitch);
--- a/cc1/symbol.c
+++ b/cc1/symbol.c
@@ -60,6 +60,25 @@
 }
 
 Symbol *
+newsym(uint8_t ns)
+{
+	Symbol *sym;
+
+	sym = malloc(sizeof(*sym));
+	sym->ns = ns;
+	sym->id = (curctx) ? ++localcnt : ++globalcnt;
+	sym->ctx = curctx;
+	sym->token = IDEN;
+	sym->flags = 0;
+	sym->name = NULL;
+	sym->type = NULL;
+	sym->hash = NULL;
+	sym->next = head;
+	head = sym;
+	return sym;
+}
+
+Symbol *
 lookup(char *s, uint8_t ns)
 {
 	Symbol *sym;
@@ -77,19 +96,16 @@
 {
 	Symbol *sym, **t;
 
-	sym = xcalloc(1, sizeof(*sym));
-	sym->name = xstrdup(s);
-	sym->ctx = curctx;
-	sym->token = IDEN;
-	sym->id = (curctx) ? ++localcnt : ++globalcnt;
+	sym = newsym(ns);
 	sym->flags |= ISDEFINED;
-	sym->ns = ns;
-	sym->next = head;
-	head = sym;
 
-	t = &htab[hash(s)];
-	sym->hash = *t;
-	return *t = sym;
+	if (s) {
+		sym->name = xstrdup(s);
+		t = &htab[hash(s)];
+		sym->hash = *t;
+		*t = sym;
+	}
+	return sym;
 }
 
 void