diff --git a/src/check_type.cpp b/src/check_type.cpp index 24434dba0..b6dfafcdc 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -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 param_value = {}; + param_value.original_ast_expr = expr; if (expr == nullptr) { return param_value; } diff --git a/src/entity.cpp b/src/entity.cpp index ab4d6fd40..3d354b9c8 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -81,6 +81,7 @@ enum ParameterValueKind { struct ParameterValue { ParameterValueKind kind; + Ast *original_ast_expr; union { ExactValue value; Ast *ast_value; @@ -126,6 +127,7 @@ struct Entity { i32 field_src_index; ParameterValue param_value; + Ast * param_expr; String thread_local_model; Entity * foreign_library; diff --git a/src/ir.cpp b/src/ir.cpp index 5c4c6f805..e9be81eb8 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -7450,8 +7450,43 @@ irValue *ir_build_builtin_proc(irProcedure *proc, Ast *expr, TypeAndValue tv, Bu 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(irProcedure *proc, Ast *expr) { u64 prev_state_flags = proc->module->state_flags; defer (proc->module->state_flags = prev_state_flags); @@ -7562,20 +7597,7 @@ irValue *ir_build_call_expr(irProcedure *proc, Ast *expr) { } else { GB_ASSERT(e->kind == Entity_Variable); if (args[i] == nullptr) { - switch (e->Variable.param_value.kind) { - 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; - } + args[i] = ir_handle_param_value(proc, e->type, e->Variable.param_value, ast_token(expr).pos); } else { 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 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; if (pt->params) { GB_ASSERT(pt->params->kind == Type_Tuple); @@ -7658,21 +7674,7 @@ irValue *ir_build_call_expr(irProcedure *proc, Ast *expr) { while (arg_index < end) { Entity *e = param_tuple->variables[arg_index]; GB_ASSERT(e->kind == Entity_Variable); - - 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; - } + args[arg_index++] = ir_handle_param_value(proc, e->type, e->Variable.param_value, ast_token(expr).pos); } } @@ -7753,20 +7755,7 @@ irValue *ir_build_call_expr(irProcedure *proc, Ast *expr) { if (variadic && variadic_index+1 < param_count) { for (isize i = variadic_index+1; i < param_count; i++) { Entity *e = param_tuple->variables[i]; - switch (e->Variable.param_value.kind) { - 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; - } + args[i] = ir_handle_param_value(proc, e->type, e->Variable.param_value, ast_token(expr).pos); } } diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 40a629d45..e2259cefb 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -370,21 +370,7 @@ void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) { while (arg_index < end) { Entity *e = param_tuple->variables[arg_index]; GB_ASSERT(e->kind == Entity_Variable); - - 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; - } + args[arg_index++] = lb_handle_param_value(p, e->type, e->Variable.param_value, pos); } } @@ -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) { lbModule *m = p->module; @@ -8166,20 +8186,7 @@ lbValue lb_build_call_expr(lbProcedure *p, Ast *expr) { } else { GB_ASSERT(e->kind == Entity_Variable); if (args[i].value == nullptr) { - switch (e->Variable.param_value.kind) { - 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; - } + args[i] = lb_handle_param_value(p, e->type, e->Variable.param_value, ast_token(expr).pos); } else { 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) { Entity *e = param_tuple->variables[arg_index]; GB_ASSERT(e->kind == Entity_Variable); - - 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; - } + args[arg_index++] = lb_handle_param_value(p, e->type, e->Variable.param_value, ast_token(expr).pos); } } @@ -8371,20 +8364,7 @@ lbValue lb_build_call_expr(lbProcedure *p, Ast *expr) { if (variadic && variadic_index+1 < param_count) { for (isize i = variadic_index+1; i < param_count; i++) { Entity *e = param_tuple->variables[i]; - switch (e->Variable.param_value.kind) { - 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; - } + args[i] = lb_handle_param_value(p, e->type, e->Variable.param_value, ast_token(expr).pos); } } diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index e6ba7730d..23b2c7654 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -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); 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_TYPE_INFO_PROC_NAME "__$startup_type_info" #define LB_TYPE_INFO_DATA_NAME "__$type_info_data" diff --git a/src/types.cpp b/src/types.cpp index 20a6bd901..65f2281aa 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -953,7 +953,6 @@ Type *alloc_type_simd_vector(i64 count, Type *elem) { - ////////////////////////////////////////////////////////////////