ref: f78f068b7f726cab481c4c95facda19f4efa8ba5
parent: b45fa07261e9c67a83dd910dfcfc44a3d8c41d1e
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Mon Aug 10 19:13:51 EDT 2015
Force to keep the order in Symbol list It is very important to keep the order in the Symbol list and hash, because in other case the block structure doesn't work. This patch modify the insertion in both data structure from head insertion to order insertion.
--- a/cc1/decl.c
+++ b/cc1/decl.c
@@ -495,12 +495,10 @@
if (sclass == NOSCLASS)
sclass = EXTERN;
/*
- * FIXME: Ugly workaround to solve function declarations.
+ * Ugly workaround to solve function declarations.
* A new context is added for the parameters,
* so at this point curctx is incremented by
* one when sym was parsed.
- * It can destroy the order of the hash when
- * there is a previous declaration in an outer contex.
*/
--curctx;
sym = install(NS_IDEN, sym);
@@ -634,7 +632,10 @@
* but due to parameter context, we have to check
* against GLOBALCTX+1
*/
- if (sym->type->op == FTN && curctx == GLOBALCTX+1) {
+ if (sym->type->op == FTN) {
+ if (curctx != GLOBALCTX+1)
+ goto remove_pars;
+
switch (yytoken) {
case '{':
case TYPEIDEN:
@@ -658,6 +659,7 @@
curfun = NULL;
return;
default:
+ remove_pars:
popctx();
}
}
--- a/cc1/symbol.c
+++ b/cc1/symbol.c
@@ -91,8 +91,7 @@
warn("'%s' defined but not used", sym->name);
}
free(sym->name);
- if (sym->type && sym->type->op == FTN)
- free(sym->u.pars);
+ // TODO: Fix this memory leak free(sym->u.pars);
free(sym);
}
hp->next = sym;
@@ -123,8 +122,21 @@
sym->name = NULL;
sym->type = NULL;
sym->hash = NULL;
- sym->next = head;
- head = sym;
+
+ if (!head || head->ctx <= curctx) {
+ 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;
}
@@ -151,7 +163,7 @@
sym = newsym(ns);
sym->name = xstrdup(yytext);
- sym->flags &= ~ISDEFINED;
+ sym->flags &= ~ISDECLARED;
sym->hash = *h;
*h = sym;
return sym;
@@ -199,8 +211,21 @@
sym = newsym(ns);
sym->name = xstrdup(name);
h = &htab[hash(name)];
- sym->hash = *h;
- *h = sym;
+
+ 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;
+ }
}
if (sym->ns != NS_CPP)
@@ -280,6 +305,7 @@
sym->token = bp->token;
sym->u.token = bp->value;
}
+ head = NULL;
ns = NS_CPPCLAUSES;
}
}