| ... | @@ -2307,6 +2307,12 @@ static IrInstruction *ir_gen_null_literal(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -2307,6 +2307,12 @@ static IrInstruction *ir_gen_null_literal(IrBuilder *irb, Scope *scope, AstNode |
| 2307 | return ir_build_const_null(irb, scope, node); | 2307 | return ir_build_const_null(irb, scope, node); |
| 2308 | } | 2308 | } |
| 2309 | | 2309 | |
| | 2310 | static IrInstruction *ir_gen_var_literal(IrBuilder *irb, Scope *scope, AstNode *node) { |
| | 2311 | assert(node->type == NodeTypeVarLiteral); |
| | 2312 | |
| | 2313 | return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_var); |
| | 2314 | } |
| | 2315 | |
| 2310 | static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, Tld *tld, | 2316 | static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, Tld *tld, |
| 2311 | LValPurpose lval, Scope *scope) | 2317 | LValPurpose lval, Scope *scope) |
| 2312 | { | 2318 | { |
| ... | @@ -3927,6 +3933,8 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop | ... | @@ -3927,6 +3933,8 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 3927 | return ir_lval_wrap(irb, scope, ir_gen_asm_expr(irb, scope, node), lval); | 3933 | return ir_lval_wrap(irb, scope, ir_gen_asm_expr(irb, scope, node), lval); |
| 3928 | case NodeTypeNullLiteral: | 3934 | case NodeTypeNullLiteral: |
| 3929 | return ir_lval_wrap(irb, scope, ir_gen_null_literal(irb, scope, node), lval); | 3935 | return ir_lval_wrap(irb, scope, ir_gen_null_literal(irb, scope, node), lval); |
| | 3936 | case NodeTypeVarLiteral: |
| | 3937 | return ir_lval_wrap(irb, scope, ir_gen_var_literal(irb, scope, node), lval); |
| 3930 | case NodeTypeIfVarExpr: | 3938 | case NodeTypeIfVarExpr: |
| 3931 | return ir_lval_wrap(irb, scope, ir_gen_if_var_expr(irb, scope, node), lval); | 3939 | return ir_lval_wrap(irb, scope, ir_gen_if_var_expr(irb, scope, node), lval); |
| 3932 | case NodeTypeSwitchExpr: | 3940 | case NodeTypeSwitchExpr: |
| ... | @@ -3949,8 +3957,6 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop | ... | @@ -3949,8 +3957,6 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 3949 | return ir_lval_wrap(irb, scope, ir_gen_slice(irb, scope, node), lval); | 3957 | return ir_lval_wrap(irb, scope, ir_gen_slice(irb, scope, node), lval); |
| 3950 | case NodeTypeUnwrapErrorExpr: | 3958 | case NodeTypeUnwrapErrorExpr: |
| 3951 | return ir_lval_wrap(irb, scope, ir_gen_err_ok_or(irb, scope, node), lval); | 3959 | return ir_lval_wrap(irb, scope, ir_gen_err_ok_or(irb, scope, node), lval); |
| 3952 | case NodeTypeZeroesLiteral: | | |
| 3953 | case NodeTypeVarLiteral: | | |
| 3954 | case NodeTypeFnProto: | 3960 | case NodeTypeFnProto: |
| 3955 | case NodeTypeFnDef: | 3961 | case NodeTypeFnDef: |
| 3956 | case NodeTypeFnDecl: | 3962 | case NodeTypeFnDecl: |
| ... | @@ -3959,6 +3965,8 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop | ... | @@ -3959,6 +3965,8 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 3959 | case NodeTypeErrorValueDecl: | 3965 | case NodeTypeErrorValueDecl: |
| 3960 | case NodeTypeTypeDecl: | 3966 | case NodeTypeTypeDecl: |
| 3961 | zig_panic("TODO more IR gen for node types"); | 3967 | zig_panic("TODO more IR gen for node types"); |
| | 3968 | case NodeTypeZeroesLiteral: |
| | 3969 | zig_panic("TODO zeroes is deprecated"); |
| 3962 | } | 3970 | } |
| 3963 | zig_unreachable(); | 3971 | zig_unreachable(); |
| 3964 | } | 3972 | } |
| ... | @@ -4065,17 +4073,18 @@ static IrInstruction *ir_exec_const_result(IrExecutable *exec) { | ... | @@ -4065,17 +4073,18 @@ static IrInstruction *ir_exec_const_result(IrExecutable *exec) { |
| 4065 | return nullptr; | 4073 | return nullptr; |
| 4066 | | 4074 | |
| 4067 | IrBasicBlock *bb = exec->basic_block_list.at(0); | 4075 | IrBasicBlock *bb = exec->basic_block_list.at(0); |
| 4068 | if (bb->instruction_list.length != 1) | 4076 | for (size_t i = 0; i < bb->instruction_list.length; i += 1) { |
| 4069 | return nullptr; | 4077 | IrInstruction *instruction = bb->instruction_list.at(i); |
| 4070 | | 4078 | if (instruction->id == IrInstructionIdReturn) { |
| 4071 | IrInstruction *only_inst = bb->instruction_list.at(0); | 4079 | IrInstructionReturn *ret_inst = (IrInstructionReturn *)instruction; |
| 4072 | if (only_inst->id != IrInstructionIdReturn) | 4080 | IrInstruction *value = ret_inst->value; |
| 4073 | return nullptr; | 4081 | assert(value->static_value.special != ConstValSpecialRuntime); |
| 4074 | | 4082 | return value; |
| 4075 | IrInstructionReturn *ret_inst = (IrInstructionReturn *)only_inst; | 4083 | } else if (ir_has_side_effects(instruction)) { |
| 4076 | IrInstruction *value = ret_inst->value; | 4084 | return nullptr; |
| 4077 | assert(value->static_value.special != ConstValSpecialRuntime); | 4085 | } |
| 4078 | return value; | 4086 | } |
| | 4087 | return nullptr; |
| 4079 | } | 4088 | } |
| 4080 | | 4089 | |
| 4081 | static bool ir_emit_global_runtime_side_effect(IrAnalyze *ira, IrInstruction *source_instruction) { | 4090 | static bool ir_emit_global_runtime_side_effect(IrAnalyze *ira, IrInstruction *source_instruction) { |
| ... | @@ -4123,9 +4132,109 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc | ... | @@ -4123,9 +4132,109 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc |
| 4123 | return false; | 4132 | return false; |
| 4124 | } | 4133 | } |
| 4125 | | 4134 | |
| 4126 | static TypeTableEntry *ir_determine_peer_types(IrAnalyze *ira, AstNode *source_node, | 4135 | enum ImplicitCastMatchResult { |
| 4127 | IrInstruction **instructions, size_t instruction_count) | 4136 | ImplicitCastMatchResultNo, |
| | 4137 | ImplicitCastMatchResultYes, |
| | 4138 | ImplicitCastMatchResultReportedError, |
| | 4139 | }; |
| | 4140 | |
| | 4141 | static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira, TypeTableEntry *expected_type, |
| | 4142 | TypeTableEntry *actual_type, IrInstruction *value) |
| 4128 | { | 4143 | { |
| | 4144 | if (types_match_const_cast_only(expected_type, actual_type)) { |
| | 4145 | return ImplicitCastMatchResultYes; |
| | 4146 | } |
| | 4147 | |
| | 4148 | // implicit conversion from anything to var |
| | 4149 | if (expected_type->id == TypeTableEntryIdVar) { |
| | 4150 | return ImplicitCastMatchResultYes; |
| | 4151 | } |
| | 4152 | |
| | 4153 | // implicit conversion from non maybe type to maybe type |
| | 4154 | if (expected_type->id == TypeTableEntryIdMaybe && |
| | 4155 | ir_types_match_with_implicit_cast(ira, expected_type->data.maybe.child_type, actual_type, value)) |
| | 4156 | { |
| | 4157 | return ImplicitCastMatchResultYes; |
| | 4158 | } |
| | 4159 | |
| | 4160 | // implicit conversion from null literal to maybe type |
| | 4161 | if (expected_type->id == TypeTableEntryIdMaybe && |
| | 4162 | actual_type->id == TypeTableEntryIdNullLit) |
| | 4163 | { |
| | 4164 | return ImplicitCastMatchResultYes; |
| | 4165 | } |
| | 4166 | |
| | 4167 | // implicit conversion from error child type to error type |
| | 4168 | if (expected_type->id == TypeTableEntryIdErrorUnion && |
| | 4169 | ir_types_match_with_implicit_cast(ira, expected_type->data.error.child_type, actual_type, value)) |
| | 4170 | { |
| | 4171 | return ImplicitCastMatchResultYes; |
| | 4172 | } |
| | 4173 | |
| | 4174 | // implicit conversion from pure error to error union type |
| | 4175 | if (expected_type->id == TypeTableEntryIdErrorUnion && |
| | 4176 | actual_type->id == TypeTableEntryIdPureError) |
| | 4177 | { |
| | 4178 | return ImplicitCastMatchResultYes; |
| | 4179 | } |
| | 4180 | |
| | 4181 | // implicit widening conversion |
| | 4182 | if (expected_type->id == TypeTableEntryIdInt && |
| | 4183 | actual_type->id == TypeTableEntryIdInt && |
| | 4184 | expected_type->data.integral.is_signed == actual_type->data.integral.is_signed && |
| | 4185 | expected_type->data.integral.bit_count >= actual_type->data.integral.bit_count) |
| | 4186 | { |
| | 4187 | return ImplicitCastMatchResultYes; |
| | 4188 | } |
| | 4189 | |
| | 4190 | // small enough unsigned ints can get casted to large enough signed ints |
| | 4191 | if (expected_type->id == TypeTableEntryIdInt && expected_type->data.integral.is_signed && |
| | 4192 | actual_type->id == TypeTableEntryIdInt && !actual_type->data.integral.is_signed && |
| | 4193 | expected_type->data.integral.bit_count > actual_type->data.integral.bit_count) |
| | 4194 | { |
| | 4195 | return ImplicitCastMatchResultYes; |
| | 4196 | } |
| | 4197 | |
| | 4198 | // implicit float widening conversion |
| | 4199 | if (expected_type->id == TypeTableEntryIdFloat && |
| | 4200 | actual_type->id == TypeTableEntryIdFloat && |
| | 4201 | expected_type->data.floating.bit_count >= actual_type->data.floating.bit_count) |
| | 4202 | { |
| | 4203 | return ImplicitCastMatchResultYes; |
| | 4204 | } |
| | 4205 | |
| | 4206 | // implicit array to slice conversion |
| | 4207 | if (expected_type->id == TypeTableEntryIdStruct && |
| | 4208 | expected_type->data.structure.is_slice && |
| | 4209 | actual_type->id == TypeTableEntryIdArray && |
| | 4210 | types_match_const_cast_only( |
| | 4211 | expected_type->data.structure.fields[0].type_entry->data.pointer.child_type, |
| | 4212 | actual_type->data.array.child_type)) |
| | 4213 | { |
| | 4214 | return ImplicitCastMatchResultYes; |
| | 4215 | } |
| | 4216 | |
| | 4217 | // implicit number literal to typed number |
| | 4218 | if ((actual_type->id == TypeTableEntryIdNumLitFloat || |
| | 4219 | actual_type->id == TypeTableEntryIdNumLitInt)) |
| | 4220 | { |
| | 4221 | if (ir_num_lit_fits_in_other_type(ira, value, expected_type)) { |
| | 4222 | return ImplicitCastMatchResultYes; |
| | 4223 | } else { |
| | 4224 | return ImplicitCastMatchResultReportedError; |
| | 4225 | } |
| | 4226 | } |
| | 4227 | |
| | 4228 | // implicit undefined literal to anything |
| | 4229 | if (actual_type->id == TypeTableEntryIdUndefLit) { |
| | 4230 | return ImplicitCastMatchResultYes; |
| | 4231 | } |
| | 4232 | |
| | 4233 | |
| | 4234 | return ImplicitCastMatchResultNo; |
| | 4235 | } |
| | 4236 | |
| | 4237 | static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, IrInstruction **instructions, size_t instruction_count) { |
| 4129 | assert(instruction_count >= 1); | 4238 | assert(instruction_count >= 1); |
| 4130 | IrInstruction *prev_inst = instructions[0]; | 4239 | IrInstruction *prev_inst = instructions[0]; |
| 4131 | if (prev_inst->type_entry->id == TypeTableEntryIdInvalid) { | 4240 | if (prev_inst->type_entry->id == TypeTableEntryIdInvalid) { |
| ... | @@ -4241,109 +4350,6 @@ static TypeTableEntry *ir_determine_peer_types(IrAnalyze *ira, AstNode *source_n | ... | @@ -4241,109 +4350,6 @@ static TypeTableEntry *ir_determine_peer_types(IrAnalyze *ira, AstNode *source_n |
| 4241 | } | 4350 | } |
| 4242 | } | 4351 | } |
| 4243 | | 4352 | |
| 4244 | enum ImplicitCastMatchResult { | | |
| 4245 | ImplicitCastMatchResultNo, | | |
| 4246 | ImplicitCastMatchResultYes, | | |
| 4247 | ImplicitCastMatchResultReportedError, | | |
| 4248 | }; | | |
| 4249 | | | |
| 4250 | static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira, TypeTableEntry *expected_type, | | |
| 4251 | TypeTableEntry *actual_type, IrInstruction *value) | | |
| 4252 | { | | |
| 4253 | if (types_match_const_cast_only(expected_type, actual_type)) { | | |
| 4254 | return ImplicitCastMatchResultYes; | | |
| 4255 | } | | |
| 4256 | | | |
| 4257 | // implicit conversion from non maybe type to maybe type | | |
| 4258 | if (expected_type->id == TypeTableEntryIdMaybe && | | |
| 4259 | ir_types_match_with_implicit_cast(ira, expected_type->data.maybe.child_type, actual_type, value)) | | |
| 4260 | { | | |
| 4261 | return ImplicitCastMatchResultYes; | | |
| 4262 | } | | |
| 4263 | | | |
| 4264 | // implicit conversion from null literal to maybe type | | |
| 4265 | if (expected_type->id == TypeTableEntryIdMaybe && | | |
| 4266 | actual_type->id == TypeTableEntryIdNullLit) | | |
| 4267 | { | | |
| 4268 | return ImplicitCastMatchResultYes; | | |
| 4269 | } | | |
| 4270 | | | |
| 4271 | // implicit conversion from error child type to error type | | |
| 4272 | if (expected_type->id == TypeTableEntryIdErrorUnion && | | |
| 4273 | ir_types_match_with_implicit_cast(ira, expected_type->data.error.child_type, actual_type, value)) | | |
| 4274 | { | | |
| 4275 | return ImplicitCastMatchResultYes; | | |
| 4276 | } | | |
| 4277 | | | |
| 4278 | // implicit conversion from pure error to error union type | | |
| 4279 | if (expected_type->id == TypeTableEntryIdErrorUnion && | | |
| 4280 | actual_type->id == TypeTableEntryIdPureError) | | |
| 4281 | { | | |
| 4282 | return ImplicitCastMatchResultYes; | | |
| 4283 | } | | |
| 4284 | | | |
| 4285 | // implicit widening conversion | | |
| 4286 | if (expected_type->id == TypeTableEntryIdInt && | | |
| 4287 | actual_type->id == TypeTableEntryIdInt && | | |
| 4288 | expected_type->data.integral.is_signed == actual_type->data.integral.is_signed && | | |
| 4289 | expected_type->data.integral.bit_count >= actual_type->data.integral.bit_count) | | |
| 4290 | { | | |
| 4291 | return ImplicitCastMatchResultYes; | | |
| 4292 | } | | |
| 4293 | | | |
| 4294 | // small enough unsigned ints can get casted to large enough signed ints | | |
| 4295 | if (expected_type->id == TypeTableEntryIdInt && expected_type->data.integral.is_signed && | | |
| 4296 | actual_type->id == TypeTableEntryIdInt && !actual_type->data.integral.is_signed && | | |
| 4297 | expected_type->data.integral.bit_count > actual_type->data.integral.bit_count) | | |
| 4298 | { | | |
| 4299 | return ImplicitCastMatchResultYes; | | |
| 4300 | } | | |
| 4301 | | | |
| 4302 | // implicit float widening conversion | | |
| 4303 | if (expected_type->id == TypeTableEntryIdFloat && | | |
| 4304 | actual_type->id == TypeTableEntryIdFloat && | | |
| 4305 | expected_type->data.floating.bit_count >= actual_type->data.floating.bit_count) | | |
| 4306 | { | | |
| 4307 | return ImplicitCastMatchResultYes; | | |
| 4308 | } | | |
| 4309 | | | |
| 4310 | // implicit array to slice conversion | | |
| 4311 | if (expected_type->id == TypeTableEntryIdStruct && | | |
| 4312 | expected_type->data.structure.is_slice && | | |
| 4313 | actual_type->id == TypeTableEntryIdArray && | | |
| 4314 | types_match_const_cast_only( | | |
| 4315 | expected_type->data.structure.fields[0].type_entry->data.pointer.child_type, | | |
| 4316 | actual_type->data.array.child_type)) | | |
| 4317 | { | | |
| 4318 | return ImplicitCastMatchResultYes; | | |
| 4319 | } | | |
| 4320 | | | |
| 4321 | // implicit number literal to typed number | | |
| 4322 | if ((actual_type->id == TypeTableEntryIdNumLitFloat || | | |
| 4323 | actual_type->id == TypeTableEntryIdNumLitInt)) | | |
| 4324 | { | | |
| 4325 | if (ir_num_lit_fits_in_other_type(ira, value, expected_type)) { | | |
| 4326 | return ImplicitCastMatchResultYes; | | |
| 4327 | } else { | | |
| 4328 | return ImplicitCastMatchResultReportedError; | | |
| 4329 | } | | |
| 4330 | } | | |
| 4331 | | | |
| 4332 | // implicit undefined literal to anything | | |
| 4333 | if (actual_type->id == TypeTableEntryIdUndefLit) { | | |
| 4334 | return ImplicitCastMatchResultYes; | | |
| 4335 | } | | |
| 4336 | | | |
| 4337 | | | |
| 4338 | return ImplicitCastMatchResultNo; | | |
| 4339 | } | | |
| 4340 | | | |
| 4341 | static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, | | |
| 4342 | IrInstruction **instructions, size_t instruction_count) | | |
| 4343 | { | | |
| 4344 | return ir_determine_peer_types(ira, source_node, instructions, instruction_count); | | |
| 4345 | } | | |
| 4346 | | | |
| 4347 | static void ir_add_alloca(IrAnalyze *ira, IrInstruction *instruction, TypeTableEntry *type_entry) { | 4353 | static void ir_add_alloca(IrAnalyze *ira, IrInstruction *instruction, TypeTableEntry *type_entry) { |
| 4348 | if (type_has_bits(type_entry) && handle_is_ptr(type_entry)) { | 4354 | if (type_has_bits(type_entry) && handle_is_ptr(type_entry)) { |
| 4349 | FnTableEntry *fn_entry = exec_fn_entry(ira->new_irb.exec); | 4355 | FnTableEntry *fn_entry = exec_fn_entry(ira->new_irb.exec); |
| ... | @@ -4746,6 +4752,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -4746,6 +4752,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 4746 | return ira->codegen->invalid_instruction; | 4752 | return ira->codegen->invalid_instruction; |
| 4747 | } | 4753 | } |
| 4748 | | 4754 | |
| | 4755 | if (wanted_type->id == TypeTableEntryIdVar) |
| | 4756 | return value; |
| | 4757 | |
| 4749 | // explicit match or non-const to const | 4758 | // explicit match or non-const to const |
| 4750 | if (types_match_const_cast_only(wanted_type, actual_type)) { | 4759 | if (types_match_const_cast_only(wanted_type, actual_type)) { |
| 4751 | return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false); | 4760 | return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false); |
| ... | @@ -5833,7 +5842,7 @@ static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node | ... | @@ -5833,7 +5842,7 @@ static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node |
| 5833 | | 5842 | |
| 5834 | Buf *param_name = param_decl_node->data.param_decl.name; | 5843 | Buf *param_name = param_decl_node->data.param_decl.name; |
| 5835 | VariableTableEntry *var = add_variable(ira->codegen, param_decl_node, | 5844 | VariableTableEntry *var = add_variable(ira->codegen, param_decl_node, |
| 5836 | *exec_scope, param_name, param_type, true, first_arg_val); | 5845 | *exec_scope, param_name, casted_arg->type_entry, true, first_arg_val); |
| 5837 | *exec_scope = var->child_scope; | 5846 | *exec_scope = var->child_scope; |
| 5838 | *next_proto_i += 1; | 5847 | *next_proto_i += 1; |
| 5839 | | 5848 | |
| ... | @@ -5852,38 +5861,49 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod | ... | @@ -5852,38 +5861,49 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod |
| 5852 | if (param_type->id == TypeTableEntryIdInvalid) | 5861 | if (param_type->id == TypeTableEntryIdInvalid) |
| 5853 | return false; | 5862 | return false; |
| 5854 | | 5863 | |
| 5855 | bool is_var_type = (param_type->id == TypeTableEntryIdVar); | 5864 | IrInstruction *casted_arg = ir_implicit_cast(ira, arg, param_type); |
| 5856 | IrInstruction *casted_arg; | 5865 | if (casted_arg->type_entry->id == TypeTableEntryIdInvalid) |
| 5857 | if (is_var_type) { | 5866 | return false; |
| 5858 | casted_arg = arg; | | |
| 5859 | } else { | | |
| 5860 | casted_arg = ir_implicit_cast(ira, arg, param_type); | | |
| 5861 | if (casted_arg->type_entry->id == TypeTableEntryIdInvalid) | | |
| 5862 | return false; | | |
| 5863 | } | | |
| 5864 | | 5867 | |
| 5865 | bool inline_arg = param_decl_node->data.param_decl.is_inline; | 5868 | bool inline_arg = param_decl_node->data.param_decl.is_inline; |
| 5866 | if (inline_arg || is_var_type) { | 5869 | bool is_var_type = (param_type->id == TypeTableEntryIdVar); |
| 5867 | ConstExprValue *arg_val = ir_resolve_const(ira, casted_arg, UndefBad); | 5870 | |
| | 5871 | ConstExprValue *arg_val; |
| | 5872 | |
| | 5873 | if (inline_arg) { |
| | 5874 | arg_val = ir_resolve_const(ira, casted_arg, UndefBad); |
| 5868 | if (!arg_val) | 5875 | if (!arg_val) |
| 5869 | return false; | 5876 | return false; |
| 5870 | | | |
| 5871 | Buf *param_name = param_decl_node->data.param_decl.name; | | |
| 5872 | VariableTableEntry *var = add_variable(ira->codegen, param_decl_node, | | |
| 5873 | *child_scope, param_name, param_type, true, arg_val); | | |
| 5874 | *child_scope = var->child_scope; | | |
| 5875 | // This generic function instance could be called with anything, so when this variable is read it | 5877 | // This generic function instance could be called with anything, so when this variable is read it |
| 5876 | // needs to know that it depends on compile time variable data. | 5878 | // needs to know that it depends on compile time variable data. |
| 5877 | var->value->depends_on_compile_var = true; | 5879 | arg_val->depends_on_compile_var = true; |
| | 5880 | } else { |
| | 5881 | arg_val = nullptr; |
| | 5882 | } |
| | 5883 | |
| | 5884 | Buf *param_name = param_decl_node->data.param_decl.name; |
| | 5885 | VariableTableEntry *var = add_variable(ira->codegen, param_decl_node, |
| | 5886 | *child_scope, param_name, casted_arg->type_entry, true, arg_val); |
| | 5887 | *child_scope = var->child_scope; |
| 5878 | | 5888 | |
| | 5889 | if (inline_arg || is_var_type) { |
| 5879 | GenericParamValue *generic_param = &generic_id->params[generic_id->param_count]; | 5890 | GenericParamValue *generic_param = &generic_id->params[generic_id->param_count]; |
| 5880 | generic_param->type = casted_arg->type_entry; | 5891 | generic_param->type = casted_arg->type_entry; |
| 5881 | generic_param->value = arg_val; | 5892 | generic_param->value = arg_val; |
| 5882 | generic_id->param_count += 1; | 5893 | generic_id->param_count += 1; |
| 5883 | } else { | 5894 | } |
| | 5895 | if (!inline_arg) { |
| | 5896 | if (type_requires_comptime(var->type)) { |
| | 5897 | ir_add_error(ira, arg, |
| | 5898 | buf_sprintf("parameter of type '%s' not allowed", buf_ptr(&var->type->name))); |
| | 5899 | return false; |
| | 5900 | } |
| | 5901 | |
| | 5902 | var->shadowable = true; |
| | 5903 | |
| 5884 | casted_args[fn_type_id->param_count] = casted_arg; | 5904 | casted_args[fn_type_id->param_count] = casted_arg; |
| 5885 | FnTypeParamInfo *param_info = &fn_type_id->param_info[fn_type_id->param_count]; | 5905 | FnTypeParamInfo *param_info = &fn_type_id->param_info[fn_type_id->param_count]; |
| 5886 | param_info->type = param_type; | 5906 | param_info->type = casted_arg->type_entry; |
| 5887 | param_info->is_noalias = param_decl_node->data.param_decl.is_noalias; | 5907 | param_info->is_noalias = param_decl_node->data.param_decl.is_noalias; |
| 5888 | impl_fn->param_source_nodes[fn_type_id->param_count] = param_decl_node; | 5908 | impl_fn->param_source_nodes[fn_type_id->param_count] = param_decl_node; |
| 5889 | fn_type_id->param_count += 1; | 5909 | fn_type_id->param_count += 1; |
| ... | @@ -6475,12 +6495,20 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP | ... | @@ -6475,12 +6495,20 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP |
| 6475 | return ira->codegen->builtin_types.entry_invalid; | 6495 | return ira->codegen->builtin_types.entry_invalid; |
| 6476 | } | 6496 | } |
| 6477 | | 6497 | |
| 6478 | // cast all literal values to the resolved type | 6498 | // cast all values to the resolved type. however we can't put cast instructions in front of the phi instruction. |
| | 6499 | // so we go back and insert the casts as the last instruction in the corresponding predecessor blocks, and |
| | 6500 | // then make sure the branch instruction is preserved. |
| | 6501 | IrBasicBlock *cur_bb = ira->new_irb.current_basic_block; |
| 6479 | for (size_t i = 0; i < new_incoming_values.length; i += 1) { | 6502 | for (size_t i = 0; i < new_incoming_values.length; i += 1) { |
| 6480 | IrInstruction *new_value = new_incoming_values.at(i); | 6503 | IrInstruction *new_value = new_incoming_values.at(i); |
| | 6504 | IrBasicBlock *predecessor = new_incoming_blocks.at(i); |
| | 6505 | IrInstruction *branch_instruction = predecessor->instruction_list.pop(); |
| | 6506 | ir_set_cursor_at_end(&ira->new_irb, predecessor); |
| 6481 | IrInstruction *casted_value = ir_implicit_cast(ira, new_value, resolved_type); | 6507 | IrInstruction *casted_value = ir_implicit_cast(ira, new_value, resolved_type); |
| 6482 | new_incoming_values.items[i] = casted_value; | 6508 | new_incoming_values.items[i] = casted_value; |
| | 6509 | predecessor->instruction_list.append(branch_instruction); |
| 6483 | } | 6510 | } |
| | 6511 | ir_set_cursor_at_end(&ira->new_irb, cur_bb); |
| 6484 | | 6512 | |
| 6485 | ir_build_phi_from(&ira->new_irb, &phi_instruction->base, new_incoming_blocks.length, | 6513 | ir_build_phi_from(&ira->new_irb, &phi_instruction->base, new_incoming_blocks.length, |
| 6486 | new_incoming_blocks.items, new_incoming_values.items); | 6514 | new_incoming_blocks.items, new_incoming_values.items); |