scc

Simple C99 Compiler
Log | Files | Refs | README | LICENSE

commit 695cff844c8fb4d44a68da49758db726f47d9288
parent 66a93a10f87bb84426e2cc1ba00bde93cdbd92e6
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Tue, 19 May 2015 14:48:33 +0200

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.

Diffstat:
cc1/decl.c | 4++--
cc1/lex.c | 6+++---
cc1/stmt.c | 28++++++++++++++--------------
cc1/symbol.c | 38+++++++++++++++++++++++++++-----------
4 files changed, 46 insertions(+), 30 deletions(-)

diff --git a/cc1/decl.c b/cc1/decl.c @@ -115,7 +115,7 @@ directdcl(struct dcldata *dp, uint8_t ns) 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 @@ newtag(uint8_t tag) next(); break; default: - sym = install("", NS_TAG); + sym = install(NULL, NS_TAG); break; } if (!sym->type) { diff --git a/cc1/lex.c b/cc1/lex.c @@ -246,7 +246,7 @@ integer(char *s, char base) 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 @@ character(void) 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 @@ repeat: } *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; diff --git a/cc1/stmt.c b/cc1/stmt.c @@ -72,9 +72,9 @@ While(Symbol *lbreak, Symbol *lcont, Caselist *lswitch) 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 @@ For(Symbol *lbreak, Symbol *lcont, Caselist *lswitch) 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 @@ Dowhile(Symbol *lbreak, Symbol *lcont, Caselist *lswitch) 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 @@ Switch(Symbol *lbreak, Symbol *lcont, Caselist *lswitch) 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 @@ Case(Symbol *lbreak, Symbol *lcont, Caselist *lswitch) 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 @@ Case(Symbol *lbreak, Symbol *lcont, Caselist *lswitch) static void Default(Symbol *lbreak, Symbol *lcont, Caselist *lswitch) { - Symbol *ldefault = install("", NS_LABEL); + Symbol *ldefault = install(NULL, NS_LABEL); expect(DEFAULT); expect(':'); @@ -285,14 +285,14 @@ If(Symbol *lbreak, Symbol *lcont, Caselist *lswitch) Symbol *end, *lelse; Node *np; - lelse = install("", NS_LABEL); + lelse = install(NULL, NS_LABEL); expect(IF); np = condition(); emit(OBRANCH, lelse); 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); diff --git a/cc1/symbol.c b/cc1/symbol.c @@ -60,6 +60,25 @@ popctx(void) } 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 @@ install(char *s, uint8_t ns) { 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