mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 23:58:50 +00:00
Fix and clean up default procedure parameter code for non-constant types
This commit is contained in:
@@ -1370,6 +1370,7 @@ bool is_expr_from_a_parameter(CheckerContext *ctx, Ast *expr) {
|
|||||||
|
|
||||||
ParameterValue handle_parameter_value(CheckerContext *ctx, Type *in_type, Type **out_type_, Ast *expr, bool allow_caller_location) {
|
ParameterValue handle_parameter_value(CheckerContext *ctx, Type *in_type, Type **out_type_, Ast *expr, bool allow_caller_location) {
|
||||||
ParameterValue param_value = {};
|
ParameterValue param_value = {};
|
||||||
|
param_value.original_ast_expr = expr;
|
||||||
if (expr == nullptr) {
|
if (expr == nullptr) {
|
||||||
return param_value;
|
return param_value;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ enum ParameterValueKind {
|
|||||||
|
|
||||||
struct ParameterValue {
|
struct ParameterValue {
|
||||||
ParameterValueKind kind;
|
ParameterValueKind kind;
|
||||||
|
Ast *original_ast_expr;
|
||||||
union {
|
union {
|
||||||
ExactValue value;
|
ExactValue value;
|
||||||
Ast *ast_value;
|
Ast *ast_value;
|
||||||
@@ -126,6 +127,7 @@ struct Entity {
|
|||||||
i32 field_src_index;
|
i32 field_src_index;
|
||||||
|
|
||||||
ParameterValue param_value;
|
ParameterValue param_value;
|
||||||
|
Ast * param_expr;
|
||||||
|
|
||||||
String thread_local_model;
|
String thread_local_model;
|
||||||
Entity * foreign_library;
|
Entity * foreign_library;
|
||||||
|
|||||||
+38
-49
@@ -7450,8 +7450,43 @@ irValue *ir_build_builtin_proc(irProcedure *proc, Ast *expr, TypeAndValue tv, Bu
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
irValue *ir_handle_param_value(irProcedure *proc, Type *parameter_type, ParameterValue const ¶m_value, TokenPos const &pos) {
|
||||||
|
switch (param_value.kind) {
|
||||||
|
case ParameterValue_Constant:
|
||||||
|
if (is_type_constant_type(parameter_type)) {
|
||||||
|
return ir_value_constant(parameter_type, param_value.value);
|
||||||
|
} else {
|
||||||
|
ExactValue ev = param_value.value;
|
||||||
|
irValue *arg = nullptr;
|
||||||
|
Type *type = type_of_expr(param_value.original_ast_expr);
|
||||||
|
if (type != nullptr) {
|
||||||
|
arg = ir_value_constant(type, ev);
|
||||||
|
} else {
|
||||||
|
arg = ir_value_constant(parameter_type, param_value.value);
|
||||||
|
}
|
||||||
|
return ir_emit_conv(proc, arg, parameter_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
case ParameterValue_Nil:
|
||||||
|
return ir_value_nil(parameter_type);
|
||||||
|
case ParameterValue_Location:
|
||||||
|
{
|
||||||
|
String proc_name = {};
|
||||||
|
if (proc->entity != nullptr) {
|
||||||
|
proc_name = proc->entity->token.string;
|
||||||
|
}
|
||||||
|
return ir_emit_source_code_location(proc, proc_name, pos);
|
||||||
|
}
|
||||||
|
case ParameterValue_Value:
|
||||||
|
return ir_build_expr(proc, param_value.ast_value);
|
||||||
|
}
|
||||||
|
return ir_value_nil(parameter_type);
|
||||||
|
}
|
||||||
|
|
||||||
irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr);
|
irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr);
|
||||||
|
|
||||||
|
|
||||||
irValue *ir_build_expr(irProcedure *proc, Ast *expr) {
|
irValue *ir_build_expr(irProcedure *proc, Ast *expr) {
|
||||||
u64 prev_state_flags = proc->module->state_flags;
|
u64 prev_state_flags = proc->module->state_flags;
|
||||||
defer (proc->module->state_flags = prev_state_flags);
|
defer (proc->module->state_flags = prev_state_flags);
|
||||||
@@ -7562,20 +7597,7 @@ irValue *ir_build_call_expr(irProcedure *proc, Ast *expr) {
|
|||||||
} else {
|
} else {
|
||||||
GB_ASSERT(e->kind == Entity_Variable);
|
GB_ASSERT(e->kind == Entity_Variable);
|
||||||
if (args[i] == nullptr) {
|
if (args[i] == nullptr) {
|
||||||
switch (e->Variable.param_value.kind) {
|
args[i] = ir_handle_param_value(proc, e->type, e->Variable.param_value, ast_token(expr).pos);
|
||||||
case ParameterValue_Constant:
|
|
||||||
args[i] = ir_value_constant(e->type, e->Variable.param_value.value);
|
|
||||||
break;
|
|
||||||
case ParameterValue_Nil:
|
|
||||||
args[i] = ir_value_nil(e->type);
|
|
||||||
break;
|
|
||||||
case ParameterValue_Location:
|
|
||||||
args[i] = ir_emit_source_code_location(proc, proc->entity->token.string, ast_token(expr).pos);
|
|
||||||
break;
|
|
||||||
case ParameterValue_Value:
|
|
||||||
args[i] = ir_build_expr(proc, e->Variable.param_value.ast_value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
args[i] = ir_emit_conv(proc, args[i], e->type);
|
args[i] = ir_emit_conv(proc, args[i], e->type);
|
||||||
}
|
}
|
||||||
@@ -7613,12 +7635,6 @@ irValue *ir_build_call_expr(irProcedure *proc, Ast *expr) {
|
|||||||
bool vari_expand = ce->ellipsis.pos.line != 0;
|
bool vari_expand = ce->ellipsis.pos.line != 0;
|
||||||
bool is_c_vararg = pt->c_vararg;
|
bool is_c_vararg = pt->c_vararg;
|
||||||
|
|
||||||
String proc_name = {};
|
|
||||||
if (proc->entity != nullptr) {
|
|
||||||
proc_name = proc->entity->token.string;
|
|
||||||
}
|
|
||||||
TokenPos pos = ast_token(ce->proc).pos;
|
|
||||||
|
|
||||||
TypeTuple *param_tuple = nullptr;
|
TypeTuple *param_tuple = nullptr;
|
||||||
if (pt->params) {
|
if (pt->params) {
|
||||||
GB_ASSERT(pt->params->kind == Type_Tuple);
|
GB_ASSERT(pt->params->kind == Type_Tuple);
|
||||||
@@ -7658,21 +7674,7 @@ irValue *ir_build_call_expr(irProcedure *proc, Ast *expr) {
|
|||||||
while (arg_index < end) {
|
while (arg_index < end) {
|
||||||
Entity *e = param_tuple->variables[arg_index];
|
Entity *e = param_tuple->variables[arg_index];
|
||||||
GB_ASSERT(e->kind == Entity_Variable);
|
GB_ASSERT(e->kind == Entity_Variable);
|
||||||
|
args[arg_index++] = ir_handle_param_value(proc, e->type, e->Variable.param_value, ast_token(expr).pos);
|
||||||
switch (e->Variable.param_value.kind) {
|
|
||||||
case ParameterValue_Constant:
|
|
||||||
args[arg_index++] = ir_value_constant(e->type, e->Variable.param_value.value);
|
|
||||||
break;
|
|
||||||
case ParameterValue_Nil:
|
|
||||||
args[arg_index++] = ir_value_nil(e->type);
|
|
||||||
break;
|
|
||||||
case ParameterValue_Location:
|
|
||||||
args[arg_index++] = ir_emit_source_code_location(proc, proc_name, pos);
|
|
||||||
break;
|
|
||||||
case ParameterValue_Value:
|
|
||||||
args[arg_index++] = ir_build_expr(proc, e->Variable.param_value.ast_value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7753,20 +7755,7 @@ irValue *ir_build_call_expr(irProcedure *proc, Ast *expr) {
|
|||||||
if (variadic && variadic_index+1 < param_count) {
|
if (variadic && variadic_index+1 < param_count) {
|
||||||
for (isize i = variadic_index+1; i < param_count; i++) {
|
for (isize i = variadic_index+1; i < param_count; i++) {
|
||||||
Entity *e = param_tuple->variables[i];
|
Entity *e = param_tuple->variables[i];
|
||||||
switch (e->Variable.param_value.kind) {
|
args[i] = ir_handle_param_value(proc, e->type, e->Variable.param_value, ast_token(expr).pos);
|
||||||
case ParameterValue_Constant:
|
|
||||||
args[i] = ir_value_constant(e->type, e->Variable.param_value.value);
|
|
||||||
break;
|
|
||||||
case ParameterValue_Nil:
|
|
||||||
args[i] = ir_value_nil(e->type);
|
|
||||||
break;
|
|
||||||
case ParameterValue_Location:
|
|
||||||
args[i] = ir_emit_source_code_location(proc, proc_name, pos);
|
|
||||||
break;
|
|
||||||
case ParameterValue_Value:
|
|
||||||
args[i] = ir_build_expr(proc, e->Variable.param_value.ast_value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+38
-58
@@ -370,21 +370,7 @@ void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) {
|
|||||||
while (arg_index < end) {
|
while (arg_index < end) {
|
||||||
Entity *e = param_tuple->variables[arg_index];
|
Entity *e = param_tuple->variables[arg_index];
|
||||||
GB_ASSERT(e->kind == Entity_Variable);
|
GB_ASSERT(e->kind == Entity_Variable);
|
||||||
|
args[arg_index++] = lb_handle_param_value(p, e->type, e->Variable.param_value, pos);
|
||||||
switch (e->Variable.param_value.kind) {
|
|
||||||
case ParameterValue_Constant:
|
|
||||||
args[arg_index++] = lb_const_value(p->module, e->type, e->Variable.param_value.value);
|
|
||||||
break;
|
|
||||||
case ParameterValue_Nil:
|
|
||||||
args[arg_index++] = lb_const_nil(m, e->type);
|
|
||||||
break;
|
|
||||||
case ParameterValue_Location:
|
|
||||||
args[arg_index++] = lb_emit_source_code_location(p, proc_name, pos);
|
|
||||||
break;
|
|
||||||
case ParameterValue_Value:
|
|
||||||
args[arg_index++] = lb_build_expr(p, e->Variable.param_value.ast_value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8072,6 +8058,40 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
lbValue lb_handle_param_value(lbProcedure *p, Type *parameter_type, ParameterValue const ¶m_value, TokenPos const &pos) {
|
||||||
|
switch (param_value.kind) {
|
||||||
|
case ParameterValue_Constant:
|
||||||
|
if (is_type_constant_type(parameter_type)) {
|
||||||
|
return lb_const_value(p->module, parameter_type, param_value.value);
|
||||||
|
} else {
|
||||||
|
ExactValue ev = param_value.value;
|
||||||
|
lbValue arg = {};
|
||||||
|
Type *type = type_of_expr(param_value.original_ast_expr);
|
||||||
|
if (type != nullptr) {
|
||||||
|
arg = lb_const_value(p->module, type, ev);
|
||||||
|
} else {
|
||||||
|
arg = lb_const_value(p->module, parameter_type, param_value.value);
|
||||||
|
}
|
||||||
|
return lb_emit_conv(p, arg, parameter_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
case ParameterValue_Nil:
|
||||||
|
return lb_const_nil(p->module, parameter_type);
|
||||||
|
case ParameterValue_Location:
|
||||||
|
{
|
||||||
|
String proc_name = {};
|
||||||
|
if (p->entity != nullptr) {
|
||||||
|
proc_name = p->entity->token.string;
|
||||||
|
}
|
||||||
|
return lb_emit_source_code_location(p, proc_name, pos);
|
||||||
|
}
|
||||||
|
case ParameterValue_Value:
|
||||||
|
return lb_build_expr(p, param_value.ast_value);
|
||||||
|
}
|
||||||
|
return lb_const_nil(p->module, parameter_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
lbValue lb_build_call_expr(lbProcedure *p, Ast *expr) {
|
lbValue lb_build_call_expr(lbProcedure *p, Ast *expr) {
|
||||||
lbModule *m = p->module;
|
lbModule *m = p->module;
|
||||||
|
|
||||||
@@ -8166,20 +8186,7 @@ lbValue lb_build_call_expr(lbProcedure *p, Ast *expr) {
|
|||||||
} else {
|
} else {
|
||||||
GB_ASSERT(e->kind == Entity_Variable);
|
GB_ASSERT(e->kind == Entity_Variable);
|
||||||
if (args[i].value == nullptr) {
|
if (args[i].value == nullptr) {
|
||||||
switch (e->Variable.param_value.kind) {
|
args[i] = lb_handle_param_value(p, e->type, e->Variable.param_value, ast_token(expr).pos);
|
||||||
case ParameterValue_Constant:
|
|
||||||
args[i] = lb_const_value(p->module, e->type, e->Variable.param_value.value);
|
|
||||||
break;
|
|
||||||
case ParameterValue_Nil:
|
|
||||||
args[i] = lb_const_nil(m, e->type);
|
|
||||||
break;
|
|
||||||
case ParameterValue_Location:
|
|
||||||
args[i] = lb_emit_source_code_location(p, p->entity->token.string, ast_token(expr).pos);
|
|
||||||
break;
|
|
||||||
case ParameterValue_Value:
|
|
||||||
args[i] = lb_build_expr(p, e->Variable.param_value.ast_value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
args[i] = lb_emit_conv(p, args[i], e->type);
|
args[i] = lb_emit_conv(p, args[i], e->type);
|
||||||
}
|
}
|
||||||
@@ -8273,21 +8280,7 @@ lbValue lb_build_call_expr(lbProcedure *p, Ast *expr) {
|
|||||||
while (arg_index < end) {
|
while (arg_index < end) {
|
||||||
Entity *e = param_tuple->variables[arg_index];
|
Entity *e = param_tuple->variables[arg_index];
|
||||||
GB_ASSERT(e->kind == Entity_Variable);
|
GB_ASSERT(e->kind == Entity_Variable);
|
||||||
|
args[arg_index++] = lb_handle_param_value(p, e->type, e->Variable.param_value, ast_token(expr).pos);
|
||||||
switch (e->Variable.param_value.kind) {
|
|
||||||
case ParameterValue_Constant:
|
|
||||||
args[arg_index++] = lb_const_value(p->module, e->type, e->Variable.param_value.value);
|
|
||||||
break;
|
|
||||||
case ParameterValue_Nil:
|
|
||||||
args[arg_index++] = lb_const_nil(m, e->type);
|
|
||||||
break;
|
|
||||||
case ParameterValue_Location:
|
|
||||||
args[arg_index++] = lb_emit_source_code_location(p, proc_name, pos);
|
|
||||||
break;
|
|
||||||
case ParameterValue_Value:
|
|
||||||
args[arg_index++] = lb_build_expr(p, e->Variable.param_value.ast_value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8371,20 +8364,7 @@ lbValue lb_build_call_expr(lbProcedure *p, Ast *expr) {
|
|||||||
if (variadic && variadic_index+1 < param_count) {
|
if (variadic && variadic_index+1 < param_count) {
|
||||||
for (isize i = variadic_index+1; i < param_count; i++) {
|
for (isize i = variadic_index+1; i < param_count; i++) {
|
||||||
Entity *e = param_tuple->variables[i];
|
Entity *e = param_tuple->variables[i];
|
||||||
switch (e->Variable.param_value.kind) {
|
args[i] = lb_handle_param_value(p, e->type, e->Variable.param_value, ast_token(expr).pos);
|
||||||
case ParameterValue_Constant:
|
|
||||||
args[i] = lb_const_value(p->module, e->type, e->Variable.param_value.value);
|
|
||||||
break;
|
|
||||||
case ParameterValue_Nil:
|
|
||||||
args[i] = lb_const_nil(m, e->type);
|
|
||||||
break;
|
|
||||||
case ParameterValue_Location:
|
|
||||||
args[i] = lb_emit_source_code_location(p, proc_name, pos);
|
|
||||||
break;
|
|
||||||
case ParameterValue_Value:
|
|
||||||
args[i] = lb_build_expr(p, e->Variable.param_value.ast_value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -352,6 +352,9 @@ void lb_store_type_case_implicit(lbProcedure *p, Ast *clause, lbValue value);
|
|||||||
lbAddr lb_store_range_stmt_val(lbProcedure *p, Ast *stmt_val, lbValue value);
|
lbAddr lb_store_range_stmt_val(lbProcedure *p, Ast *stmt_val, lbValue value);
|
||||||
lbValue lb_emit_source_code_location(lbProcedure *p, String const &procedure, TokenPos const &pos);
|
lbValue lb_emit_source_code_location(lbProcedure *p, String const &procedure, TokenPos const &pos);
|
||||||
|
|
||||||
|
lbValue lb_handle_param_value(lbProcedure *p, Type *parameter_type, ParameterValue const ¶m_value, TokenPos const &pos);
|
||||||
|
|
||||||
|
|
||||||
#define LB_STARTUP_RUNTIME_PROC_NAME "__$startup_runtime"
|
#define LB_STARTUP_RUNTIME_PROC_NAME "__$startup_runtime"
|
||||||
#define LB_STARTUP_TYPE_INFO_PROC_NAME "__$startup_type_info"
|
#define LB_STARTUP_TYPE_INFO_PROC_NAME "__$startup_type_info"
|
||||||
#define LB_TYPE_INFO_DATA_NAME "__$type_info_data"
|
#define LB_TYPE_INFO_DATA_NAME "__$type_info_data"
|
||||||
|
|||||||
@@ -953,7 +953,6 @@ Type *alloc_type_simd_vector(i64 count, Type *elem) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user