scc

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

commit 50dbcccb8762cbad40ebd87b42787c15d68c7c5b
parent ed927690e4c089521410d92c9d3b06dbc33b95bd
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Sat,  8 Mar 2014 10:08:54 +0100

Embed the ctype into the symbol

This is the common case, so it is a good idea because it simplifies
memory management.

Diffstat:
Mdecl.c | 38+++++++++++++++++++-------------------
Mexpr.c | 2+-
Mlex.c | 4++--
Msymbol.h | 6+++---
Mtypes.c | 1+
5 files changed, 26 insertions(+), 25 deletions(-)

diff --git a/decl.c b/decl.c @@ -31,7 +31,7 @@ directdcl(register struct ctype *tp, unsigned char ns) } else if (yytoken == IDEN) { /* we can't overflow due to the check in structdcl */ *symstackp++ = cursym = lookup(yytext, ns); - if (!cursym->ctype) + if (!cursym->ctype.defined) cursym->ctx = curctx; else if (cursym->ctx == curctx) error("redeclaration of '%s'", yytext); @@ -65,8 +65,6 @@ directdcl(register struct ctype *tp, unsigned char ns) } } -/* TODO: Add the type to the symbol */ - static struct symbol * aggregate(register struct ctype *tp) { @@ -77,17 +75,18 @@ aggregate(register struct ctype *tp) register struct ctype *aux; sym = lookup(yytext, NS_TAG); - if (aux = sym->ctype) { + aux = &sym->ctype; + if (aux->defined) { if (aux->type != tp->type) { error("'%s' defined as wrong kind of tag", yytext); } *tp = *aux; } else { - sym->ctype = tp; - tp->sym = sym; - tp->ns = ++nr_tags; /* FIX: It is only necessary */ - } /* in struct and union */ + tp->tag = sym->name; + tp->ns = ++nr_tags; + sym->ctype = *tp; + } next(); /* This way of handling nr_tag */ } else { /* is incorrect once is incorrect*/ tp->ns = ++nr_tags; /* it will be incorrect forever*/ @@ -133,7 +132,7 @@ fielddcl(unsigned char ns) cursym->name); } } - cursym->ctype = tp; + cursym->ctype = *tp; cursym->qlf = qlf; } while (accept(',')); @@ -150,21 +149,20 @@ structdcl(register struct ctype *tp) if (!accept('{')) return; - if (sym && !sym->ctype->forward) + if (sym && !sym->ctype.forward) error("struct/union already defined"); if (nested_tags == NR_STRUCT_LEVEL) error("too much nested structs/unions"); ++nested_tags; - do + while (!accept('}')) fielddcl(tp->ns); - while (!accept('}')); --nested_tags; + if (sym) + sym->ctype.forward = 0; tp->forward = 0; - if (sym = tp->sym) - *sym->ctype = *tp; } static void @@ -183,7 +181,7 @@ enumdcl(struct ctype *base) if (yytoken != IDEN) break; sym = lookup(yytext, NS_IDEN); - sym->ctype = tp; + sym->ctype = *tp; next(); if (accept('=')) { expect(CONSTANT); @@ -230,9 +228,10 @@ specifier(register struct ctype *tp, register struct symbol *sym; sym = lookup(yytext, NS_IDEN); - if (sym->ctype && sym->store.c_typedef) { + if (sym->ctype.defined && + sym->store.c_typedef) { tp = ctype(tp, TYPEDEF); - tp->base = sym->ctype; + tp->base = &sym->ctype; break; } } @@ -339,7 +338,8 @@ listdcl(struct ctype *base, struct storage *store, struct qualifier *qlf) declarator(base, NS_IDEN); cursym->store = *store; cursym->qlf = *qlf; - tp = cursym->ctype = decl_type(base); + cursym->ctype = *decl_type(base); + tp = &cursym->ctype; if ((tp->type == STRUCT || tp->type == UNION) && tp->forward) error("declaration of variable with incomplete type"); @@ -374,7 +374,7 @@ repeat: initctype(&base); switch (type) { case STRUCT: case UNION: - if (!base.sym) { + if (!base.tag) { warn(options.useless, "unnamed struct/union that defines no instances"); } diff --git a/expr.c b/expr.c @@ -18,7 +18,7 @@ primary(void) switch (yytoken) { case IDEN: sym = lookup(yytext, NS_IDEN); - if (!sym->ctype) + if (!sym->ctype.defined) error("'%s' undeclared", yytext); next(); np = nodesym(sym); diff --git a/lex.c b/lex.c @@ -51,9 +51,9 @@ type: switch (ch = toupper(getc(yyin))) { v = strtoll(s, NULL, base); sym = lookup(NULL, NS_IDEN); - sym->ctype = tp; + sym->ctype = *tp; - switch (sym->ctype->type) { + switch (tp->type) { case INT: sym->i = v; break; diff --git a/symbol.h b/symbol.h @@ -42,17 +42,17 @@ struct ctype { bool forward : 1; bool defined: 1; union { - unsigned len; struct { - struct symbol *sym; unsigned char ns; + char *tag; }; + unsigned len; }; struct ctype *base; }; struct symbol { - struct ctype *ctype; + struct ctype ctype; struct storage store; struct qualifier qlf; unsigned char ctx; diff --git a/types.c b/types.c @@ -80,6 +80,7 @@ mktype(register struct ctype *tp, unsigned char op) default: assert(0); } + tp->defined = 1; return tp; }