commit a06b587d1805b93e880efea3773c084b6111d0c6
parent 481870312e7a7e2389e138a97698811977541970
Author: damia <alejandro.berna@sener.es>
Date: Tue, 20 Dec 2016 17:33:01 +0100
[cc1] Add a new hash table for cpp symbols
The code of the symbol table is really complex because
we only have a hashtable, and it is creating some
situations that are complex. This is the first patch
of a serie and it does not change too much of the
structure of the code.
Diffstat:
6 files changed, 36 insertions(+), 42 deletions(-)
diff --git a/cc1/cc1.h b/cc1/cc1.h
@@ -9,6 +9,10 @@
/*
* Definition of enumerations
*/
+enum {
+ NOALLOC,
+ ALLOC
+};
enum typeprops {
TDEFINED = 1 << 0, /* type defined */
@@ -364,7 +368,7 @@ extern void flushtypes(void);
/* symbol.c */
extern void dumpstab(char *msg);
-extern Symbol *lookup(int ns, char *name);
+extern Symbol *lookup(int ns, char *name, int alloc);
extern Symbol *nextsym(Symbol *sym, int ns);
extern Symbol *install(int ns, Symbol *sym);
extern Symbol *newsym(int ns);
diff --git a/cc1/cpp.c b/cc1/cpp.c
@@ -41,7 +41,7 @@ defdefine(char *macro, char *val, char *source)
void
undefmacro(char *s)
{
- killsym(lookup(NS_CPP, s));
+ killsym(lookup(NS_CPP, s, NOALLOC));
}
void
@@ -84,8 +84,8 @@ icpp(void)
defdefine("__LINE__", NULL, "built-in");
defdefine("__FILE__", NULL, "built-in");
- symline = lookup(NS_CPP, "__LINE__");
- symfile = lookup(NS_CPP, "__FILE__");
+ symline = lookup(NS_CPP, "__LINE__", ALLOC);
+ symfile = lookup(NS_CPP, "__FILE__", ALLOC);
for (bp = list; *bp; ++bp)
defdefine(*bp, "1", "built-in");
@@ -248,18 +248,6 @@ expand(char *begin, Symbol *sym)
char *arglist[NR_MACROARG], arguments[INPUTSIZ], buffer[BUFSIZE];
macroname = sym->name;
- if ((sym->flags & SDECLARED) == 0) {
- if (namespace == NS_CPP && !strcmp(sym->name, "defined"))
- return 0; /* we found a 'defined in an #if */
- /*
- * This case happens in #if were macro not defined must
- * be expanded to 0
- */
- buffer[0] = '0';
- buffer[1] = '\0';
- elen = 1;
- goto substitute;
- }
if (sym == symfile) {
elen = sprintf(buffer, "\"%s\" ", input->fname);
goto substitute;
diff --git a/cc1/expr.c b/cc1/expr.c
@@ -666,26 +666,27 @@ primary(void)
emit(ODECL, sym);
emit(OINIT, np);
np = varnode(sym);
- next();
break;
case CONSTANT:
np = constnode(sym);
- next();
break;
case IDEN:
- if ((sym->flags & SDECLARED) == 0)
+ assert((sym->flags & SCONSTANT) == 0);
+ if ((sym->flags & SDECLARED) == 0) {
+ if (namespace == NS_CPP) {
+ np = constnode(zero);
+ break;
+ }
sym = notdefined(sym);
- if (sym->flags & SCONSTANT) {
- np = constnode(sym);
- break;
}
sym->flags |= SUSED;
np = varnode(sym);
- next();
break;
default:
unexpected();
}
+ next();
+
return np;
}
diff --git a/cc1/lex.c b/cc1/lex.c
@@ -496,8 +496,7 @@ iden(void)
/* nothing */;
input->p = p;
tok2str();
- sym = lookup(namespace, yytext);
- if (sym->ns == NS_CPP) {
+ if ((sym = lookup(NS_CPP, yytext, NOALLOC)) != NULL) {
if (!disexpand && expand(begin, sym))
return next();
/*
@@ -507,6 +506,7 @@ iden(void)
if (lexmode != CPPMODE)
sym = nextsym(sym, namespace);
}
+ sym = lookup(namespace, yytext, ALLOC);
yylval.sym = sym;
if (sym->flags & SCONSTANT)
return CONSTANT;
diff --git a/cc1/stmt.c b/cc1/stmt.c
@@ -20,7 +20,7 @@ label(void)
switch (yytoken) {
case IDEN:
case TYPEIDEN:
- sym = lookup(NS_LABEL, yytext);
+ sym = lookup(NS_LABEL, yytext, ALLOC);
if (sym->flags & SDEFINED)
error("label '%s' already defined", yytext);
if ((sym->flags & SDECLARED) == 0)
diff --git a/cc1/symbol.c b/cc1/symbol.c
@@ -16,6 +16,7 @@ static unsigned short counterid;
static Symbol *head, *labels;
static Symbol *htab[NR_SYM_HASH];
+static Symbol *htabcpp[NR_SYM_HASH];
#ifndef NDEBUG
void
@@ -56,11 +57,12 @@ hash(const char *s)
static void
unlinkhash(Symbol *sym)
{
- Symbol **h, *p, *prev;
+ Symbol **tab, **h, *p, *prev;
if ((sym->flags & SDECLARED) == 0)
return;
- h = &htab[hash(sym->name)];
+ tab = (sym->ns == NS_CPP) ? htabcpp : htab;
+ h = &tab[hash(sym->name)];
for (prev = p = *h; p != sym; prev = p, p = p->hash)
/* nothing */;
if (prev == p)
@@ -82,6 +84,8 @@ killsym(Symbol *sym)
short f;
char *name;
+ if (!sym)
+ return;
f = sym->flags;
if (f & SSTRING)
free(sym->u.s);
@@ -188,9 +192,10 @@ linksym(Symbol *sym)
static Symbol *
linkhash(Symbol *sym)
{
- Symbol **h, *p, *prev;
+ Symbol **tab, **h, *p, *prev;
- h = &htab[hash(sym->name)];
+ tab = (sym->ns == NS_CPP) ? htabcpp : htab;
+ h = &tab[hash(sym->name)];
for (prev = p = *h; p; prev = p, p = p->hash) {
if (p->ctx <= sym->ctx)
break;
@@ -241,38 +246,34 @@ newlabel(void)
}
Symbol *
-lookup(int ns, char *name)
+lookup(int ns, char *name, int alloc)
{
- Symbol *sym;
+ Symbol *sym, **tab;
int sns;
char *t, c;
c = *name;
- for (sym = htab[hash(name)]; sym; sym = sym->hash) {
+ tab = (ns == NS_CPP) ? htabcpp : htab;
+ for (sym = tab[hash(name)]; sym; sym = sym->hash) {
t = sym->name;
if (*t != c || strcmp(t, name))
continue;
sns = sym->ns;
+ if (sns == ns)
+ return sym;
/*
- * CPP namespace has a total priority over the another
- * namespaces, because it is a previous pass,
- * If we are looking in the CPP namespace,
- * we don't want symbols related to keywords or types.
* When a lookup is done in a namespace associated
* to a struct we also want symbols of NS_IDEN which
* are typedef, because in other case we cannot declare
* fields of such types.
+ * TODO: Remove this trick
*/
- if (sns == NS_CPP && !disexpand || sns == ns)
- return sym;
- if (ns == NS_CPP)
- continue;
if (sns == NS_KEYWORD ||
(sym->flags & STYPEDEF) && ns >= NS_STRUCTS) {
return sym;
}
}
- return allocsym(ns, name);
+ return (alloc == ALLOC) ? allocsym(ns, name) : NULL;
}
Symbol *