diff options
Diffstat (limited to 'src/ir.cpp')
| -rw-r--r-- | src/ir.cpp | 73 |
1 files changed, 51 insertions, 22 deletions
diff --git a/src/ir.cpp b/src/ir.cpp index a2e8cb32d..29152e5b6 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -7167,32 +7167,53 @@ void ir_begin_procedure_body(irProcedure *proc) { proc->return_ptr = param; } - if (proc->type->Proc.params != nullptr) { - ast_node(pt, ProcType, proc->type_expr); - isize param_index = 0; - isize q_index = 0; + GB_ASSERT(proc->type != nullptr); + if (proc->type->Proc.params != nullptr) { TypeTuple *params = &proc->type->Proc.params->Tuple; - for_array(i, params->variables) { - ast_node(fl, FieldList, pt->params); - GB_ASSERT(fl->list.count > 0); - GB_ASSERT(fl->list[0]->kind == AstNode_Field); - if (q_index == fl->list[param_index]->Field.names.count) { - q_index = 0; - param_index++; - } - ast_node(field, Field, fl->list[param_index]); - AstNode *name = field->names[q_index++]; - - Entity *e = params->variables[i]; - if (e->kind != Entity_Variable) { - continue; + if (proc->type_expr != nullptr) { + ast_node(pt, ProcType, proc->type_expr); + isize param_index = 0; + isize q_index = 0; + + for_array(i, params->variables) { + ast_node(fl, FieldList, pt->params); + GB_ASSERT(fl->list.count > 0); + GB_ASSERT(fl->list[0]->kind == AstNode_Field); + if (q_index == fl->list[param_index]->Field.names.count) { + q_index = 0; + param_index++; + } + ast_node(field, Field, fl->list[param_index]); + AstNode *name = field->names[q_index++]; + + Entity *e = params->variables[i]; + if (e->kind != Entity_Variable) { + continue; + } + + Type *abi_type = proc->type->Proc.abi_compat_params[i]; + if (e->token.string != "" && !is_blank_ident(e->token)) { + irValue *param = ir_add_param(proc, e, name, abi_type); + array_add(&proc->params, param); + } } + } else { + Type **abi_types = proc->type->Proc.abi_compat_params; - Type *abi_type = proc->type->Proc.abi_compat_params[i]; - if (e->token.string != "" && !is_blank_ident(e->token)) { - irValue *param = ir_add_param(proc, e, name, abi_type); - array_add(&proc->params, param); + for_array(i, params->variables) { + Entity *e = params->variables[i]; + if (e->kind != Entity_Variable) { + continue; + } + Type *abi_type = e->type; + if (abi_types != nullptr) { + abi_type = proc->type->Proc.abi_compat_params[i]; + } + if (e->token.string != "" && !is_blank_ident(e->token)) { + irValue *param = ir_add_param(proc, e, nullptr, abi_type); + array_add(&proc->params, param); + } } } } @@ -7771,6 +7792,7 @@ void ir_gen_tree(irGen *s) { proc_params->Tuple.variables[1] = make_entity_param(a, proc_scope, make_token_ident(str_lit("reason")), t_i32, false, false); proc_params->Tuple.variables[2] = make_entity_param(a, proc_scope, blank_token, t_rawptr, false, false); + proc_results->Tuple.variables[0] = make_entity_param(a, proc_scope, empty_token, t_i32, false, false); @@ -7778,6 +7800,13 @@ void ir_gen_tree(irGen *s) { proc_params, 3, proc_results, 1, false, ProcCC_Std); + // TODO(bill): make this more robust + proc_type->Proc.abi_compat_params = gb_alloc_array(a, Type *, proc_params->Tuple.variables.count); + for_array(i, proc_params->Tuple.variables) { + proc_type->Proc.abi_compat_params[i] = proc_params->Tuple.variables[i]->type; + } + proc_type->Proc.abi_compat_result_type = proc_results->Tuple.variables[0]->type; + AstNode *body = gb_alloc_item(a, AstNode); Entity *e = make_entity_procedure(a, nullptr, make_token_ident(name), proc_type, 0); irValue *p = ir_value_procedure(a, m, e, proc_type, nullptr, body, name); |