scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit f78f068b7f726cab481c4c95facda19f4efa8ba5
parent b45fa07261e9c67a83dd910dfcfc44a3d8c41d1e
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Mon, 10 Aug 2015 23:13:51 +0200

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.

Diffstat:
Mcc1/decl.c | 10++++++----
Mcc1/symbol.c | 40+++++++++++++++++++++++++++++++++-------
2 files changed, 39 insertions(+), 11 deletions(-)

diff --git a/cc1/decl.c b/cc1/decl.c @@ -495,12 +495,10 @@ identifier(Symbol *sym, Type *tp, unsigned ns, int sclass, Type *data) 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 @@ decl(void) * 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 @@ decl(void) curfun = NULL; return; default: + remove_pars: popctx(); } } diff --git a/cc1/symbol.c b/cc1/symbol.c @@ -91,8 +91,7 @@ popctx(void) 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 @@ newsym(unsigned ns) 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 @@ lookup(unsigned ns) sym = newsym(ns); sym->name = xstrdup(yytext); - sym->flags &= ~ISDEFINED; + sym->flags &= ~ISDECLARED; sym->hash = *h; *h = sym; return sym; @@ -199,8 +211,21 @@ install(unsigned ns, Symbol *sym) 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 @@ ikeywords(void) sym->token = bp->token; sym->u.token = bp->value; } + head = NULL; ns = NS_CPPCLAUSES; } }