mirror of
https://github.com/odin-lang/Odin.git
synced 2025-12-29 01:14:40 +00:00
Improve behaviour of return with named results to aid with defer statements
This commit is contained in:
25
src/ir.cpp
25
src/ir.cpp
@@ -10164,6 +10164,14 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) {
|
||||
v = ir_build_expr(proc, rs->results[0]);
|
||||
v = ir_emit_conv(proc, v, e->type);
|
||||
}
|
||||
if (proc->type->Proc.has_named_results) {
|
||||
// NOTE(bill): store the named values before returning
|
||||
if (e->token.string != "") {
|
||||
irValue **found = map_get(&proc->module->values, hash_entity(e));
|
||||
GB_ASSERT(found != nullptr);
|
||||
ir_emit_store(proc, *found, v);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&proc->module->tmp_arena);
|
||||
defer (gb_temp_arena_memory_end(tmp));
|
||||
@@ -10196,6 +10204,23 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) {
|
||||
|
||||
GB_ASSERT(results.count == return_count);
|
||||
|
||||
if (proc->type->Proc.has_named_results) {
|
||||
// NOTE(bill): store the named values before returning
|
||||
for_array(i, tuple->variables) {
|
||||
Entity *e = tuple->variables[i];
|
||||
if (e->kind != Entity_Variable) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (e->token.string == "") {
|
||||
continue;
|
||||
}
|
||||
irValue **found = map_get(&proc->module->values, hash_entity(e));
|
||||
GB_ASSERT(found != nullptr);
|
||||
ir_emit_store(proc, *found, results[i]);
|
||||
}
|
||||
}
|
||||
|
||||
Type *ret_type = proc->type->Proc.results;
|
||||
// NOTE(bill): Doesn't need to be zero because it will be initialized in the loops
|
||||
v = ir_add_local_generated(proc, ret_type, false);
|
||||
|
||||
@@ -2434,7 +2434,6 @@ void lb_begin_procedure_body(lbProcedure *p) {
|
||||
if (p->type->Proc.has_named_results) {
|
||||
GB_ASSERT(p->type->Proc.result_count > 0);
|
||||
TypeTuple *results = &p->type->Proc.results->Tuple;
|
||||
LLVMValueRef return_ptr = LLVMGetParam(p->value, 0);
|
||||
|
||||
isize result_index = 0;
|
||||
|
||||
@@ -4192,6 +4191,15 @@ void lb_build_stmt(lbProcedure *p, Ast *node) {
|
||||
res = lb_build_expr(p, rs->results[0]);
|
||||
res = lb_emit_conv(p, res, e->type);
|
||||
}
|
||||
if (p->type->Proc.has_named_results) {
|
||||
// NOTE(bill): store the named values before returning
|
||||
if (e->token.string != "") {
|
||||
lbValue *found = map_get(&p->module->values, hash_entity(e));
|
||||
GB_ASSERT(found != nullptr);
|
||||
lb_emit_store(p, *found, res);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
auto results = array_make<lbValue>(heap_allocator(), 0, return_count);
|
||||
|
||||
@@ -4221,6 +4229,23 @@ void lb_build_stmt(lbProcedure *p, Ast *node) {
|
||||
|
||||
GB_ASSERT(results.count == return_count);
|
||||
|
||||
if (p->type->Proc.has_named_results) {
|
||||
// NOTE(bill): store the named values before returning
|
||||
for_array(i, p->type->Proc.results->Tuple.variables) {
|
||||
Entity *e = p->type->Proc.results->Tuple.variables[i];
|
||||
if (e->kind != Entity_Variable) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (e->token.string == "") {
|
||||
continue;
|
||||
}
|
||||
lbValue *found = map_get(&p->module->values, hash_entity(e));
|
||||
GB_ASSERT(found != nullptr);
|
||||
lb_emit_store(p, *found, results[i]);
|
||||
}
|
||||
}
|
||||
|
||||
Type *ret_type = p->type->Proc.results;
|
||||
// NOTE(bill): Doesn't need to be zero because it will be initialized in the loops
|
||||
res = lb_add_local_generated(p, ret_type, false).addr;
|
||||
|
||||
Reference in New Issue
Block a user