harec

[hare] Hare compiler, written in C11 for POSIX OSs
Log | Files | Refs | README | LICENSE

commit 858404bda6a1a4cbc789905d1028ae73f98e7cbf
parent 2eccbc4b959a590dda91143c8487edda841106d9
Author: Armin Weigl <tb46305@gmail.com>
Date:   Tue, 21 Jun 2022 21:48:00 +0200

check: replace ctx.resolving_enum with ctx.scope

solving an issue related to shadowing variables withhin enum scopes on
the way

Signed-off-by: Armin Weigl <tb46305@gmail.com>

Diffstat:
Minclude/check.h | 1-
Msrc/check.c | 20++++++--------------
Mtests/15-enums.ha | 13+++++++++----
3 files changed, 15 insertions(+), 19 deletions(-)

diff --git a/include/check.h b/include/check.h @@ -41,7 +41,6 @@ struct context { bool is_test; struct scope *unit; struct scope *scope; - struct scope *resolving_enum; bool deferring; int id; struct errors *errors; diff --git a/src/check.c b/src/check.c @@ -146,12 +146,7 @@ check_expr_access(struct context *ctx, const struct scope_object *obj = NULL; switch (expr->access.type) { case ACCESS_IDENTIFIER: - if (ctx->resolving_enum) { - obj = scope_lookup(ctx->resolving_enum, &aexpr->access.ident); - } - if (!obj) { - obj = scope_lookup(ctx->scope, &aexpr->access.ident); - } + obj = scope_lookup(ctx->scope, &aexpr->access.ident); if (!obj) { char buf[1024]; identifier_unparse_static(&aexpr->access.ident, @@ -3504,6 +3499,7 @@ incomplete_types_create(struct context *ctx, struct scope *imp, struct ast_decl scope_push((struct scope **)&type->_enum.values, SCOPE_ENUM); incomplete_enum_field_create(ctx, imp, type->_enum.values, type, t->type->_enum.values); + type->_enum.values->parent = ctx->unit; scope_insert(ctx->scope, O_TYPE, &with_ns, &t->ident, type, NULL); } else { @@ -3621,7 +3617,6 @@ resolve_enum_field(struct context *ctx, const struct scope_object *obj) { assert(obj->otype == O_SCAN); struct incomplete_declaration *idecl = (struct incomplete_declaration*)obj; - assert(ctx->resolving_enum == NULL); assert(idecl->type == IDECL_ENUM_FLD); const struct type *type = idecl->field->type; @@ -3658,7 +3653,7 @@ resolve_enum_field(struct context *ctx, const struct scope_object *obj) idecl = (struct incomplete_declaration *)obj; assert(idecl->type == IDECL_ENUM_FLD); - ctx->resolving_enum = idecl->field->enum_scope; + ctx->scope = idecl->field->enum_scope; struct expression *value = xcalloc(1, sizeof(struct expression)); value->result = type; if (idecl->field->field->value) { // explicit value @@ -3704,7 +3699,6 @@ resolve_enum_field(struct context *ctx, const struct scope_object *obj) } } } - ctx->resolving_enum = NULL; return scope_insert(idecl->field->enum_scope, O_CONST, &name, &localname, type, value); } @@ -3972,8 +3966,7 @@ wrap_resolver(struct context *ctx, const struct scope_object *obj, resolvefn resolver) { // save current subunit and enum context - struct scope *enum_scope = ctx->resolving_enum; - ctx->resolving_enum = NULL; + struct scope *scope = ctx->scope; struct scope *subunit = ctx->unit->parent; ctx->unit->parent = NULL; @@ -3985,6 +3978,7 @@ wrap_resolver(struct context *ctx, const struct scope_object *obj, } // load this declaration's subunit context + ctx->scope = ctx->unit; ctx->unit->parent = idecl->imports; // resolving a declaration that is already in progress -> cycle @@ -4005,7 +3999,7 @@ wrap_resolver(struct context *ctx, const struct scope_object *obj, exit: // load stored context ctx->unit->parent = subunit; - ctx->resolving_enum = enum_scope; + ctx->scope = scope; idecl->in_progress = false; return obj; } @@ -4233,14 +4227,12 @@ check_internal(struct type_store *ts, } // Perform actual declaration resolution - ctx.resolving_enum = NULL; for (const struct scope_object *obj = ctx.scope->objects; obj; obj = obj->lnext) { if (obj->otype != O_SCAN) { continue; } wrap_resolver(&ctx, obj, resolve_decl); - assert(ctx.resolving_enum == NULL); } handle_errors(ctx.errors); diff --git a/tests/15-enums.ha b/tests/15-enums.ha @@ -129,16 +129,19 @@ fn aliases() void = { assert(imported_double_alias::THREE == testmod::_enum::THREE); }; -// Force T2 to be resolved before T1 +// Force T2 to be resolved before t2::T3 and t2::T3 before t2::T1 type t1 = enum { I1 = t2::T1, - I2 = t2::T2, + I2 = t2::T3, + I3 = T2: int, }; +def T2: uint = 0; + type t2 = enum { T1, T2 = 1, - T3, + T3 = T2 + 1, }; export fn resolution_order() void = { @@ -146,7 +149,9 @@ export fn resolution_order() void = { assert(t2::T2 == 1); assert(t2::T3 == 2); assert(t1::I1 == 0); - assert(t1::I2 == 1); + assert(t1::I2 == 2); + assert(t1::I3 == 0); + assert(T2 == 0); }; export fn main() void = {