mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Allow nested procedures to access @(static) and @(thread_local) variables
This commit is contained in:
+4
-2
@@ -1075,8 +1075,10 @@ Entity *check_ident(CheckerContext *c, Operand *o, Ast *n, Type *named_type, Typ
|
|||||||
if (e->parent_proc_decl != nullptr &&
|
if (e->parent_proc_decl != nullptr &&
|
||||||
e->parent_proc_decl != c->curr_proc_decl) {
|
e->parent_proc_decl != c->curr_proc_decl) {
|
||||||
if (e->kind == Entity_Variable) {
|
if (e->kind == Entity_Variable) {
|
||||||
error(n, "Nested procedures do not capture its parent's variables: %.*s", LIT(name));
|
if ((e->flags & EntityFlag_Static) == 0) {
|
||||||
return nullptr;
|
error(n, "Nested procedures do not capture its parent's variables: %.*s", LIT(name));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
} else if (e->kind == Entity_Label) {
|
} else if (e->kind == Entity_Label) {
|
||||||
error(n, "Nested procedures do not capture its parent's labels: %.*s", LIT(name));
|
error(n, "Nested procedures do not capture its parent's labels: %.*s", LIT(name));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|||||||
+8
-3
@@ -368,9 +368,14 @@ void scope_lookup_parent(Scope *scope, String const &name, Scope **scope_, Entit
|
|||||||
if (e->kind == Entity_Label) {
|
if (e->kind == Entity_Label) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (e->kind == Entity_Variable &&
|
if (e->kind == Entity_Variable) {
|
||||||
!(e->scope->flags&ScopeFlag_File)) {
|
if (e->scope->flags&ScopeFlag_File) {
|
||||||
continue;
|
// Global variables are file to access
|
||||||
|
} else if (e->flags&EntityFlag_Static) {
|
||||||
|
// Allow static/thread_local variables to be referenced
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+23
-9
@@ -12875,6 +12875,7 @@ void lb_generate_code(lbGenerator *gen) {
|
|||||||
lbValue var;
|
lbValue var;
|
||||||
lbValue init;
|
lbValue init;
|
||||||
DeclInfo *decl;
|
DeclInfo *decl;
|
||||||
|
bool is_initialized;
|
||||||
};
|
};
|
||||||
auto global_variables = array_make<GlobalVariable>(permanent_allocator(), 0, global_variable_max_count);
|
auto global_variables = array_make<GlobalVariable>(permanent_allocator(), 0, global_variable_max_count);
|
||||||
|
|
||||||
@@ -12937,15 +12938,22 @@ void lb_generate_code(lbGenerator *gen) {
|
|||||||
var.var = g;
|
var.var = g;
|
||||||
var.decl = decl;
|
var.decl = decl;
|
||||||
|
|
||||||
if (decl->init_expr != nullptr && !is_type_any(e->type)) {
|
if (decl->init_expr != nullptr) {
|
||||||
TypeAndValue tav = type_and_value_of_expr(decl->init_expr);
|
TypeAndValue tav = type_and_value_of_expr(decl->init_expr);
|
||||||
if (tav.mode != Addressing_Invalid) {
|
if (!is_type_any(e->type)) {
|
||||||
if (tav.value.kind != ExactValue_Invalid) {
|
if (tav.mode != Addressing_Invalid) {
|
||||||
ExactValue v = tav.value;
|
if (tav.value.kind != ExactValue_Invalid) {
|
||||||
lbValue init = lb_const_value(m, tav.type, v);
|
ExactValue v = tav.value;
|
||||||
LLVMSetInitializer(g.value, init.value);
|
lbValue init = lb_const_value(m, tav.type, v);
|
||||||
|
LLVMSetInitializer(g.value, init.value);
|
||||||
|
var.is_initialized = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!var.is_initialized &&
|
||||||
|
(is_type_untyped_nil(tav.type) || is_type_untyped_undef(tav.type))) {
|
||||||
|
var.is_initialized = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
array_add(&global_variables, var);
|
array_add(&global_variables, var);
|
||||||
@@ -13146,10 +13154,13 @@ void lb_generate_code(lbGenerator *gen) {
|
|||||||
auto *var = &global_variables[i];
|
auto *var = &global_variables[i];
|
||||||
if (var->decl->init_expr != nullptr) {
|
if (var->decl->init_expr != nullptr) {
|
||||||
lbValue init = lb_build_expr(p, var->decl->init_expr);
|
lbValue init = lb_build_expr(p, var->decl->init_expr);
|
||||||
if (!lb_is_const(init)) {
|
if (lb_is_const(init)) {
|
||||||
var->init = init;
|
if (!var->is_initialized) {
|
||||||
|
LLVMSetInitializer(var->var.value, init.value);
|
||||||
|
var->is_initialized = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
LLVMSetInitializer(var->var.value, init.value);
|
var->init = init;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -13166,6 +13177,7 @@ void lb_generate_code(lbGenerator *gen) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (var->init.value != nullptr) {
|
if (var->init.value != nullptr) {
|
||||||
|
GB_ASSERT(!var->is_initialized);
|
||||||
Type *t = type_deref(var->var.type);
|
Type *t = type_deref(var->var.type);
|
||||||
|
|
||||||
if (is_type_any(t)) {
|
if (is_type_any(t)) {
|
||||||
@@ -13182,6 +13194,8 @@ void lb_generate_code(lbGenerator *gen) {
|
|||||||
} else {
|
} else {
|
||||||
lb_emit_store(p, var->var, lb_emit_conv(p, var->init, t));
|
lb_emit_store(p, var->var, lb_emit_conv(p, var->init, t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var->is_initialized = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user