shithub: scc

Download patch

ref: 407b3b6c257984402dd3c7980ba5ac32290f8ad4
parent: c20c165fc5a69576846c832a43d044a157a35561
author: damia <alejandro.berna@sener.es>
date: Tue Dec 20 12:33:01 EST 2016

[cc1] Add a new hash table for cpp symbols

The code of the symbol table is really complex because
we only have a hashtable, and it is creating some
situations that are complex. This is the first patch
of a serie and it does not change too much of the
structure of the code.

--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -9,6 +9,10 @@
 /*
  * Definition of enumerations
  */
+enum {
+	NOALLOC,
+	ALLOC
+};
 
 enum typeprops {
 	TDEFINED = 1 << 0,    /* type defined */
@@ -364,7 +368,7 @@
 
 /* symbol.c */
 extern void dumpstab(char *msg);
-extern Symbol *lookup(int ns, char *name);
+extern Symbol *lookup(int ns, char *name, int alloc);
 extern Symbol *nextsym(Symbol *sym, int ns);
 extern Symbol *install(int ns, Symbol *sym);
 extern Symbol *newsym(int ns);
--- a/cc1/cpp.c
+++ b/cc1/cpp.c
@@ -41,7 +41,7 @@
 void
 undefmacro(char *s)
 {
-	killsym(lookup(NS_CPP, s));
+	killsym(lookup(NS_CPP, s, NOALLOC));
 }
 
 void
@@ -84,8 +84,8 @@
 	defdefine("__LINE__", NULL, "built-in");
 	defdefine("__FILE__", NULL, "built-in");
 
-	symline = lookup(NS_CPP, "__LINE__");
-	symfile = lookup(NS_CPP, "__FILE__");
+	symline = lookup(NS_CPP, "__LINE__", ALLOC);
+	symfile = lookup(NS_CPP, "__FILE__", ALLOC);
 
 	for (bp = list; *bp; ++bp)
 		defdefine(*bp, "1", "built-in");
@@ -248,18 +248,6 @@
 	char *arglist[NR_MACROARG], arguments[INPUTSIZ], buffer[BUFSIZE];
 
 	macroname = sym->name;
-	if ((sym->flags & SDECLARED) == 0) {
-		if (namespace == NS_CPP && !strcmp(sym->name, "defined"))
-			return 0;  /* we found a 'defined in an #if */
-		/*
-		 * This case happens in #if were macro not defined must
-		 * be expanded to 0
-		 */
-		buffer[0] = '0';
-		buffer[1] = '\0';
-		elen = 1;
-		goto substitute;
-	}
 	if (sym == symfile) {
 		elen = sprintf(buffer, "\"%s\" ", input->fname);
 		goto substitute;
--- a/cc1/expr.c
+++ b/cc1/expr.c
@@ -666,26 +666,27 @@
 		emit(ODECL, sym);
 		emit(OINIT, np);
 		np = varnode(sym);
-		next();
 		break;
 	case CONSTANT:
 		np = constnode(sym);
-		next();
 		break;
 	case IDEN:
-		if ((sym->flags & SDECLARED) == 0)
+		assert((sym->flags & SCONSTANT) == 0);
+		if ((sym->flags & SDECLARED) == 0) {
+			if (namespace == NS_CPP) {
+				np = constnode(zero);
+				break;
+			}
 			sym = notdefined(sym);
-		if (sym->flags & SCONSTANT) {
-			np = constnode(sym);
-			break;
 		}
 		sym->flags |= SUSED;
 		np = varnode(sym);
-		next();
 		break;
 	default:
 		unexpected();
 	}
+	next();
+
 	return np;
 }
 
--- a/cc1/lex.c
+++ b/cc1/lex.c
@@ -496,8 +496,7 @@
 		/* nothing */;
 	input->p = p;
 	tok2str();
-	sym = lookup(namespace, yytext);
-	if (sym->ns == NS_CPP) {
+	if ((sym = lookup(NS_CPP, yytext, NOALLOC)) != NULL) {
 		if (!disexpand && expand(begin, sym))
 			return next();
 		/*
@@ -507,6 +506,7 @@
 		if (lexmode != CPPMODE)
 			sym = nextsym(sym, namespace);
 	}
+	sym = lookup(namespace, yytext, ALLOC);
 	yylval.sym = sym;
 	if (sym->flags & SCONSTANT)
 		return CONSTANT;
--- a/cc1/stmt.c
+++ b/cc1/stmt.c
@@ -20,7 +20,7 @@
 	switch (yytoken) {
 	case IDEN:
 	case TYPEIDEN:
-		sym = lookup(NS_LABEL, yytext);
+		sym = lookup(NS_LABEL, yytext, ALLOC);
 		if (sym->flags & SDEFINED)
 			error("label '%s' already defined", yytext);
 		if ((sym->flags & SDECLARED) == 0)
--- a/cc1/symbol.c
+++ b/cc1/symbol.c
@@ -16,6 +16,7 @@
 
 static Symbol *head, *labels;
 static Symbol *htab[NR_SYM_HASH];
+static Symbol *htabcpp[NR_SYM_HASH];
 
 #ifndef NDEBUG
 void
@@ -56,11 +57,12 @@
 static void
 unlinkhash(Symbol *sym)
 {
-	Symbol **h, *p, *prev;
+	Symbol **tab, **h, *p, *prev;
 
 	if ((sym->flags & SDECLARED) == 0)
 		return;
-	h = &htab[hash(sym->name)];
+	tab = (sym->ns == NS_CPP) ? htabcpp : htab;
+	h = &tab[hash(sym->name)];
 	for (prev = p = *h; p != sym; prev = p, p = p->hash)
 		/* nothing */;
 	if (prev == p)
@@ -82,6 +84,8 @@
 	short f;
 	char *name;
 
+	if (!sym)
+		return;
 	f = sym->flags;
 	if (f & SSTRING)
 		free(sym->u.s);
@@ -188,9 +192,10 @@
 static Symbol *
 linkhash(Symbol *sym)
 {
-	Symbol **h, *p, *prev;
+	Symbol **tab, **h, *p, *prev;
 
-	h = &htab[hash(sym->name)];
+	tab = (sym->ns == NS_CPP) ? htabcpp : htab;
+	h = &tab[hash(sym->name)];
 	for (prev = p = *h; p; prev = p, p = p->hash) {
 		if (p->ctx <= sym->ctx)
 			break;
@@ -241,38 +246,34 @@
 }
 
 Symbol *
-lookup(int ns, char *name)
+lookup(int ns, char *name, int alloc)
 {
-	Symbol *sym;
+	Symbol *sym, **tab;
 	int sns;
 	char *t, c;
 
 	c = *name;
-	for (sym = htab[hash(name)]; sym; sym = sym->hash) {
+	tab = (ns == NS_CPP) ? htabcpp : htab;
+	for (sym = tab[hash(name)]; sym; sym = sym->hash) {
 		t = sym->name;
 		if (*t != c || strcmp(t, name))
 			continue;
 		sns = sym->ns;
+		if (sns == ns)
+			return sym;
 		/*
-		 * CPP namespace has a total priority over the another
-		 * namespaces, because it is a previous pass,
-		 * If we are looking in the CPP namespace,
-		 * we don't want symbols related to keywords or types.
 		 * When a lookup is done in a namespace associated
 		 * to a struct we also want symbols of NS_IDEN which
 		 * are typedef, because in other case we cannot declare
 		 * fields of such types.
+		 * TODO: Remove this trick
 		 */
-		if (sns == NS_CPP && !disexpand || sns == ns)
-			return sym;
-		if (ns == NS_CPP)
-			continue;
 		if (sns == NS_KEYWORD ||
 		    (sym->flags & STYPEDEF) && ns >= NS_STRUCTS) {
 			return sym;
 		}
 	}
-	return allocsym(ns, name);
+	return (alloc == ALLOC) ? allocsym(ns, name) : NULL;
 }
 
 Symbol *