commit d092be22d3220430733d7fb532d72d6a2348e9d1
parent f6df05343dbc81b5f3f8f1fa129007b3dd4a47fc
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Tue, 11 Aug 2015 11:53:31 +0200
Keep hash order in lookup() too
The order was not preserved in lookup(), which was
inserting always in the head.
Diffstat:
M | cc1/symbol.c | | | 89 | +++++++++++++++++++++++++++++++++++++++++++++++-------------------------------- |
1 file changed, 53 insertions(+), 36 deletions(-)
diff --git a/cc1/symbol.c b/cc1/symbol.c
@@ -53,6 +53,44 @@ hash(const char *s)
return h & NR_SYM_HASH-1;
}
+static Symbol *
+linkhash(Symbol *sym, char *name)
+{
+ Symbol **h, *p, *prev;
+
+ sym->name = xstrdup(name);
+ h = &htab[hash(name)];
+
+ for (prev = p = *h; p; prev = p, p = p->hash) {
+ if (p->ctx <= sym->ctx)
+ break;
+ }
+ if (p == prev) {
+ sym->hash = *h;
+ *h = sym;
+ } else {
+ p = prev->hash;
+ prev->hash = sym;
+ sym->hash = p;
+ }
+
+ return sym;
+}
+
+static void
+unlinkhash(Symbol *sym)
+{
+ Symbol **h, *p, *prev;
+
+ h = &htab[hash(sym->name)];
+ for (prev = p = *h; p != sym; prev = p, p = p->hash)
+ /* nothing */;
+ if (prev == p)
+ *h = sym->hash;
+ else
+ prev->hash = sym->hash;
+}
+
void
pushctx(void)
{
@@ -94,7 +132,7 @@ popctx(void)
}
if (sym->name) {
short f = sym->flags;
- htab[hash(sym->name)] = sym->hash;
+ unlinkhash(sym);
if ((f & (ISUSED|ISGLOBAL|ISDECLARED)) == ISDECLARED)
warn("'%s' defined but not used", sym->name);
}
@@ -119,7 +157,7 @@ duptype(Type *base)
Symbol *
newsym(unsigned ns)
{
- Symbol *sym;
+ Symbol *sym, *p, *prev;
sym = malloc(sizeof(*sym));
sym->id = 0;
@@ -129,22 +167,24 @@ newsym(unsigned ns)
sym->flags = ISDECLARED;
sym->name = NULL;
sym->type = NULL;
- sym->hash = NULL;
+ sym->next = sym->hash = NULL;
+
+ if (ns == NS_CPP)
+ return sym;
- if (!head || head->ctx <= curctx) {
+ for (prev = p = head; p; prev = p, p = p->next) {
+ if (p->ctx <= sym->ctx)
+ break;
+ }
+ if (p == prev) {
sym->next = head;
head = sym;
} else {
- Symbol *p, *prev;
-
- for (prev = p = head; p; prev = p, p = p->next) {
- if (p->ctx <= sym->ctx)
- break;
- }
p = prev->next;
prev->next = sym;
sym->next = p;
}
+
return sym;
}
@@ -168,12 +208,9 @@ lookup(unsigned ns)
continue;
return sym;
}
-
- sym = newsym(ns);
- sym->name = xstrdup(yytext);
+ sym = linkhash(newsym(ns), yytext);
sym->flags &= ~ISDECLARED;
- sym->hash = *h;
- *h = sym;
+
return sym;
}
@@ -213,27 +250,7 @@ install(unsigned ns, Symbol *sym)
return NULL;
sym->flags |= ISDECLARED;
} else {
- char *name = sym->name;
- Symbol **h;
-
- sym = newsym(ns);
- sym->name = xstrdup(name);
- h = &htab[hash(name)];
-
- if (!*h || (*h)->ctx <= curctx) {
- sym->hash = *h;
- *h = sym;
- } else {
- Symbol *p, *prev;
-
- for (prev = p = *h; p; prev = p, p = p->hash) {
- if (p->ctx <= sym->ctx)
- break;
- }
- p = prev->hash;
- prev->hash = sym;
- sym->hash = p;
- }
+ sym = linkhash(newsym(ns), sym->name);
}
if (sym->ns != NS_CPP)