mirror of https://github.com/rui314/chibicc
Use hashmap for block-scope lookup
This commit is contained in:
parent
30520e5a7c
commit
655954e301
62
parse.c
62
parse.c
|
@ -20,23 +20,12 @@
|
|||
|
||||
// Scope for local variables, global variables, typedefs
|
||||
// or enum constants
|
||||
typedef struct VarScope VarScope;
|
||||
struct VarScope {
|
||||
VarScope *next;
|
||||
char *name;
|
||||
typedef struct {
|
||||
Obj *var;
|
||||
Type *type_def;
|
||||
Type *enum_ty;
|
||||
int enum_val;
|
||||
};
|
||||
|
||||
// Scope for struct, union or enum tags
|
||||
typedef struct TagScope TagScope;
|
||||
struct TagScope {
|
||||
TagScope *next;
|
||||
char *name;
|
||||
Type *ty;
|
||||
};
|
||||
} VarScope;
|
||||
|
||||
// Represents a block scope.
|
||||
typedef struct Scope Scope;
|
||||
|
@ -45,8 +34,8 @@ struct Scope {
|
|||
|
||||
// C has two block scopes; one is for variables/typedefs and
|
||||
// the other is for struct/union/enum tags.
|
||||
VarScope *vars;
|
||||
TagScope *tags;
|
||||
HashMap vars;
|
||||
HashMap tags;
|
||||
};
|
||||
|
||||
// Variable attributes such as typedef or extern.
|
||||
|
@ -183,18 +172,20 @@ static void leave_scope(void) {
|
|||
|
||||
// Find a variable by name.
|
||||
static VarScope *find_var(Token *tok) {
|
||||
for (Scope *sc = scope; sc; sc = sc->next)
|
||||
for (VarScope *sc2 = sc->vars; sc2; sc2 = sc2->next)
|
||||
if (equal(tok, sc2->name))
|
||||
return sc2;
|
||||
for (Scope *sc = scope; sc; sc = sc->next) {
|
||||
VarScope *sc2 = hashmap_get2(&sc->vars, tok->loc, tok->len);
|
||||
if (sc2)
|
||||
return sc2;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Type *find_tag(Token *tok) {
|
||||
for (Scope *sc = scope; sc; sc = sc->next)
|
||||
for (TagScope *sc2 = sc->tags; sc2; sc2 = sc2->next)
|
||||
if (equal(tok, sc2->name))
|
||||
return sc2->ty;
|
||||
for (Scope *sc = scope; sc; sc = sc->next) {
|
||||
Type *ty = hashmap_get2(&sc->tags, tok->loc, tok->len);
|
||||
if (ty)
|
||||
return ty;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -263,9 +254,7 @@ Node *new_cast(Node *expr, Type *ty) {
|
|||
|
||||
static VarScope *push_scope(char *name) {
|
||||
VarScope *sc = calloc(1, sizeof(VarScope));
|
||||
sc->name = name;
|
||||
sc->next = scope->vars;
|
||||
scope->vars = sc;
|
||||
hashmap_put(&scope->vars, name, sc);
|
||||
return sc;
|
||||
}
|
||||
|
||||
|
@ -366,11 +355,7 @@ static Type *find_typedef(Token *tok) {
|
|||
}
|
||||
|
||||
static void push_tag_scope(Token *tok, Type *ty) {
|
||||
TagScope *sc = calloc(1, sizeof(TagScope));
|
||||
sc->name = strndup(tok->loc, tok->len);
|
||||
sc->ty = ty;
|
||||
sc->next = scope->tags;
|
||||
scope->tags = sc;
|
||||
hashmap_put2(&scope->tags, tok->loc, tok->len, ty);
|
||||
}
|
||||
|
||||
// declspec = ("void" | "_Bool" | "char" | "short" | "int" | "long"
|
||||
|
@ -2559,11 +2544,10 @@ static Type *struct_union_decl(Token **rest, Token *tok) {
|
|||
if (tag) {
|
||||
// If this is a redefinition, overwrite a previous type.
|
||||
// Otherwise, register the struct type.
|
||||
for (TagScope *sc = scope->tags; sc; sc = sc->next) {
|
||||
if (equal(tag, sc->name)) {
|
||||
*sc->ty = *ty;
|
||||
return sc->ty;
|
||||
}
|
||||
Type *ty2 = hashmap_get2(&scope->tags, tag->loc, tag->len);
|
||||
if (ty2) {
|
||||
*ty2 = *ty;
|
||||
return ty2;
|
||||
}
|
||||
|
||||
push_tag_scope(tag, ty);
|
||||
|
@ -3053,9 +3037,9 @@ static Obj *find_func(char *name) {
|
|||
while (sc->next)
|
||||
sc = sc->next;
|
||||
|
||||
for (VarScope *sc2 = sc->vars; sc2; sc2 = sc2->next)
|
||||
if (!strcmp(sc2->name, name) && sc2->var && sc2->var->is_function)
|
||||
return sc2->var;
|
||||
VarScope *sc2 = hashmap_get(&sc->vars, name);
|
||||
if (sc2 && sc2->var && sc2->var->is_function)
|
||||
return sc2->var;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue