ref: 407b3b6c257984402dd3c7980ba5ac32290f8ad4
parent: c20c165fc5a69576846c832a43d044a157a35561
author: damia <alejandro.berna@sener.es>
date: Tue Dec 20 12:33:01 EST 2016
[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.
--- 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 @@
/* 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);
--- a/cc1/cpp.c
+++ b/cc1/cpp.c
@@ -41,7 +41,7 @@
void
undefmacro(char *s)
{
- killsym(lookup(NS_CPP, s));
+ killsym(lookup(NS_CPP, s, NOALLOC));
}
void
@@ -84,8 +84,8 @@
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 @@
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;
--- a/cc1/expr.c
+++ b/cc1/expr.c
@@ -666,26 +666,27 @@
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;
}
--- a/cc1/lex.c
+++ b/cc1/lex.c
@@ -496,8 +496,7 @@
/* 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 @@
if (lexmode != CPPMODE)
sym = nextsym(sym, namespace);
}
+ sym = lookup(namespace, yytext, ALLOC);
yylval.sym = sym;
if (sym->flags & SCONSTANT)
return CONSTANT;
--- a/cc1/stmt.c
+++ b/cc1/stmt.c
@@ -20,7 +20,7 @@
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)
--- a/cc1/symbol.c
+++ b/cc1/symbol.c
@@ -16,6 +16,7 @@
static Symbol *head, *labels;
static Symbol *htab[NR_SYM_HASH];
+static Symbol *htabcpp[NR_SYM_HASH];
#ifndef NDEBUG
void
@@ -56,11 +57,12 @@
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 @@
short f;
char *name;
+ if (!sym)
+ return;
f = sym->flags;
if (f & SSTRING)
free(sym->u.s);
@@ -188,9 +192,10 @@
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 @@
}
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 *