| ... | @@ -2119,7 +2119,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo | ... | @@ -2119,7 +2119,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo |
| 2119 | child_scope = elem_var->child_scope; | 2119 | child_scope = elem_var->child_scope; |
| 2120 | | 2120 | |
| 2121 | IrInstruction *undefined_value = ir_build_const_undefined(irb, child_scope, elem_node); | 2121 | IrInstruction *undefined_value = ir_build_const_undefined(irb, child_scope, elem_node); |
| 2122 | ir_build_var_decl(irb, child_scope, elem_node, elem_var, elem_var_type, undefined_value); | 2122 | ir_build_var_decl(irb, child_scope, elem_node, elem_var, elem_var_type, undefined_value); |
| 2123 | IrInstruction *elem_var_ptr = ir_build_var_ptr(irb, child_scope, node, elem_var); | 2123 | IrInstruction *elem_var_ptr = ir_build_var_ptr(irb, child_scope, node, elem_var); |
| 2124 | | 2124 | |
| 2125 | AstNode *index_var_source_node; | 2125 | AstNode *index_var_source_node; |
| ... | @@ -2137,7 +2137,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo | ... | @@ -2137,7 +2137,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo |
| 2137 | IrInstruction *usize = ir_build_const_type(irb, child_scope, node, irb->codegen->builtin_types.entry_usize); | 2137 | IrInstruction *usize = ir_build_const_type(irb, child_scope, node, irb->codegen->builtin_types.entry_usize); |
| 2138 | IrInstruction *zero = ir_build_const_usize(irb, child_scope, node, 0); | 2138 | IrInstruction *zero = ir_build_const_usize(irb, child_scope, node, 0); |
| 2139 | IrInstruction *one = ir_build_const_usize(irb, child_scope, node, 1); | 2139 | IrInstruction *one = ir_build_const_usize(irb, child_scope, node, 1); |
| 2140 | ir_build_var_decl(irb, child_scope, index_var_source_node, index_var, usize, zero); | 2140 | ir_build_var_decl(irb, child_scope, index_var_source_node, index_var, usize, zero); |
| 2141 | IrInstruction *index_ptr = ir_build_var_ptr(irb, child_scope, node, index_var); | 2141 | IrInstruction *index_ptr = ir_build_var_ptr(irb, child_scope, node, index_var); |
| 2142 | | 2142 | |
| 2143 | | 2143 | |
| ... | @@ -2347,7 +2347,7 @@ static IrInstruction *ir_gen_if_var_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -2347,7 +2347,7 @@ static IrInstruction *ir_gen_if_var_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 2347 | | 2347 | |
| 2348 | IrInstruction *var_ptr_value = ir_build_unwrap_maybe(irb, scope, node, expr_value, false); | 2348 | IrInstruction *var_ptr_value = ir_build_unwrap_maybe(irb, scope, node, expr_value, false); |
| 2349 | IrInstruction *var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, scope, node, var_ptr_value); | 2349 | IrInstruction *var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, scope, node, var_ptr_value); |
| 2350 | ir_build_var_decl(irb, scope, node, var, var_type, var_value); | 2350 | ir_build_var_decl(irb, scope, node, var, var_type, var_value); |
| 2351 | IrInstruction *then_expr_result = ir_gen_node(irb, then_node, var->child_scope); | 2351 | IrInstruction *then_expr_result = ir_gen_node(irb, then_node, var->child_scope); |
| 2352 | if (then_expr_result == irb->codegen->invalid_instruction) | 2352 | if (then_expr_result == irb->codegen->invalid_instruction) |
| 2353 | return then_expr_result; | 2353 | return then_expr_result; |
| ... | @@ -2405,7 +2405,7 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *swit | ... | @@ -2405,7 +2405,7 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *swit |
| 2405 | var_value = var_is_ptr ? target_value_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, target_value_ptr); | 2405 | var_value = var_is_ptr ? target_value_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, target_value_ptr); |
| 2406 | } | 2406 | } |
| 2407 | IrInstruction *var_type = nullptr; // infer the type | 2407 | IrInstruction *var_type = nullptr; // infer the type |
| 2408 | ir_build_var_decl(irb, scope, var_symbol_node, var, var_type, var_value); | 2408 | ir_build_var_decl(irb, scope, var_symbol_node, var, var_type, var_value); |
| 2409 | } else { | 2409 | } else { |
| 2410 | child_scope = scope; | 2410 | child_scope = scope; |
| 2411 | } | 2411 | } |
| ... | @@ -3287,44 +3287,6 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node | ... | @@ -3287,44 +3287,6 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node |
| 3287 | return result; | 3287 | return result; |
| 3288 | } | 3288 | } |
| 3289 | | 3289 | |
| 3290 | static IrInstruction *ir_eval_fn(IrAnalyze *ira, IrInstruction *source_instruction, | | |
| 3291 | FnTableEntry *fn_entry, IrInstruction **args) | | |
| 3292 | { | | |
| 3293 | if (!fn_entry) { | | |
| 3294 | ir_add_error(ira, source_instruction, | | |
| 3295 | buf_sprintf("unable to evaluate constant expression")); | | |
| 3296 | return ira->codegen->invalid_instruction; | | |
| 3297 | } | | |
| 3298 | | | |
| 3299 | if (!ir_emit_backward_branch(ira, source_instruction)) | | |
| 3300 | return ira->codegen->invalid_instruction; | | |
| 3301 | | | |
| 3302 | TypeTableEntry *fn_type = fn_entry->type_entry; | | |
| 3303 | FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; | | |
| 3304 | | | |
| 3305 | // Fork a scope of the function with known values for the parameters. | | |
| 3306 | | | |
| 3307 | Scope *exec_scope = &fn_entry->fndef_scope->base; | | |
| 3308 | for (size_t i = 0; i < fn_type_id->param_count; i += 1) { | | |
| 3309 | AstNode *param_decl_node = fn_entry->proto_node->data.fn_proto.params.at(i); | | |
| 3310 | Buf *param_name = param_decl_node->data.param_decl.name; | | |
| 3311 | IrInstruction *arg = args[i]; | | |
| 3312 | ConstExprValue *arg_val = ir_resolve_const(ira, arg); | | |
| 3313 | if (!arg_val) | | |
| 3314 | return ira->codegen->invalid_instruction; | | |
| 3315 | | | |
| 3316 | VariableTableEntry *var = add_variable(ira->codegen, param_decl_node, exec_scope, param_name, | | |
| 3317 | arg->type_entry, true, arg_val); | | |
| 3318 | exec_scope = var->child_scope; | | |
| 3319 | } | | |
| 3320 | | | |
| 3321 | // Analyze the fn body block like any other constant expression. | | |
| 3322 | | | |
| 3323 | AstNode *body_node = fn_entry->fn_def_node->data.fn_def.body; | | |
| 3324 | return ir_eval_const_value(ira->codegen, exec_scope, body_node, fn_type_id->return_type, | | |
| 3325 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota); | | |
| 3326 | } | | |
| 3327 | | | |
| 3328 | static TypeTableEntry *ir_resolve_type_lval(IrAnalyze *ira, IrInstruction *type_value, LValPurpose lval) { | 3290 | static TypeTableEntry *ir_resolve_type_lval(IrAnalyze *ira, IrInstruction *type_value, LValPurpose lval) { |
| 3329 | if (lval != LValPurposeNone) | 3291 | if (lval != LValPurposeNone) |
| 3330 | zig_panic("TODO"); | 3292 | zig_panic("TODO"); |
| ... | @@ -4257,6 +4219,33 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc | ... | @@ -4257,6 +4219,33 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc |
| 4257 | return ira->codegen->builtin_types.entry_void; | 4219 | return ira->codegen->builtin_types.entry_void; |
| 4258 | } | 4220 | } |
| 4259 | | 4221 | |
| | 4222 | static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node, |
| | 4223 | IrInstruction *arg, Scope **exec_scope, size_t *next_arg_index) |
| | 4224 | { |
| | 4225 | AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_arg_index); |
| | 4226 | assert(param_decl_node->type == NodeTypeParamDecl); |
| | 4227 | AstNode *param_type_node = param_decl_node->data.param_decl.type; |
| | 4228 | TypeTableEntry *param_type = analyze_type_expr(ira->codegen, *exec_scope, param_type_node); |
| | 4229 | if (param_type->id == TypeTableEntryIdInvalid) |
| | 4230 | return false; |
| | 4231 | |
| | 4232 | IrInstruction *casted_arg = ir_get_casted_value(ira, arg, param_type); |
| | 4233 | if (casted_arg->type_entry->id == TypeTableEntryIdInvalid) |
| | 4234 | return false; |
| | 4235 | |
| | 4236 | ConstExprValue *first_arg_val = ir_resolve_const(ira, casted_arg); |
| | 4237 | if (!first_arg_val) |
| | 4238 | return false; |
| | 4239 | |
| | 4240 | Buf *param_name = param_decl_node->data.param_decl.name; |
| | 4241 | VariableTableEntry *var = add_variable(ira->codegen, param_decl_node, |
| | 4242 | *exec_scope, param_name, param_type, true, first_arg_val); |
| | 4243 | *exec_scope = var->child_scope; |
| | 4244 | *next_arg_index += 1; |
| | 4245 | |
| | 4246 | return true; |
| | 4247 | } |
| | 4248 | |
| 4260 | static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call_instruction, | 4249 | static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call_instruction, |
| 4261 | FnTableEntry *fn_entry, TypeTableEntry *fn_type, IrInstruction *fn_ref, | 4250 | FnTableEntry *fn_entry, TypeTableEntry *fn_type, IrInstruction *fn_ref, |
| 4262 | IrInstruction *first_arg_ptr, bool is_inline) | 4251 | IrInstruction *first_arg_ptr, bool is_inline) |
| ... | @@ -4289,8 +4278,58 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal | ... | @@ -4289,8 +4278,58 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal |
| 4289 | return ira->codegen->builtin_types.entry_invalid; | 4278 | return ira->codegen->builtin_types.entry_invalid; |
| 4290 | } | 4279 | } |
| 4291 | | 4280 | |
| | 4281 | if (is_inline) { |
| | 4282 | if (!fn_entry) { |
| | 4283 | ir_add_error(ira, fn_ref, buf_sprintf("unable to evaluate constant expression")); |
| | 4284 | return ira->codegen->builtin_types.entry_invalid; |
| | 4285 | } |
| | 4286 | |
| | 4287 | if (!ir_emit_backward_branch(ira, &call_instruction->base)) |
| | 4288 | return ira->codegen->builtin_types.entry_invalid; |
| | 4289 | |
| | 4290 | // Fork a scope of the function with known values for the parameters. |
| | 4291 | Scope *exec_scope = &fn_entry->fndef_scope->base; |
| | 4292 | |
| | 4293 | size_t next_arg_index = 0; |
| | 4294 | if (first_arg_ptr) { |
| | 4295 | IrInstruction *first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr); |
| | 4296 | if (first_arg->type_entry->id == TypeTableEntryIdInvalid) |
| | 4297 | return ira->codegen->builtin_types.entry_invalid; |
| | 4298 | |
| | 4299 | if (!ir_analyze_fn_call_inline_arg(ira, fn_proto_node, first_arg, &exec_scope, &next_arg_index)) |
| | 4300 | return ira->codegen->builtin_types.entry_invalid; |
| | 4301 | } |
| | 4302 | |
| | 4303 | for (size_t call_i = 0; call_i < call_instruction->arg_count; call_i += 1) { |
| | 4304 | IrInstruction *old_arg = call_instruction->args[call_i]->other; |
| | 4305 | if (old_arg->type_entry->id == TypeTableEntryIdInvalid) |
| | 4306 | return ira->codegen->builtin_types.entry_invalid; |
| | 4307 | |
| | 4308 | if (!ir_analyze_fn_call_inline_arg(ira, fn_proto_node, old_arg, &exec_scope, &next_arg_index)) |
| | 4309 | return ira->codegen->builtin_types.entry_invalid; |
| | 4310 | } |
| | 4311 | |
| | 4312 | AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type; |
| | 4313 | TypeTableEntry *return_type = analyze_type_expr(ira->codegen, exec_scope, return_type_node); |
| | 4314 | if (return_type->id == TypeTableEntryIdInvalid) |
| | 4315 | return ira->codegen->builtin_types.entry_invalid; |
| | 4316 | |
| | 4317 | // Analyze the fn body block like any other constant expression. |
| | 4318 | AstNode *body_node = fn_entry->fn_def_node->data.fn_def.body; |
| | 4319 | IrInstruction *result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type, |
| | 4320 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota); |
| | 4321 | if (result->type_entry->id == TypeTableEntryIdInvalid) |
| | 4322 | return ira->codegen->builtin_types.entry_invalid; |
| | 4323 | |
| | 4324 | ConstExprValue *out_val = ir_build_const_from(ira, &call_instruction->base, |
| | 4325 | result->static_value.depends_on_compile_var); |
| | 4326 | *out_val = result->static_value; |
| | 4327 | return ir_finish_anal(ira, return_type); |
| | 4328 | } |
| | 4329 | |
| 4292 | IrInstruction **casted_args = allocate<IrInstruction *>(call_param_count); | 4330 | IrInstruction **casted_args = allocate<IrInstruction *>(call_param_count); |
| 4293 | size_t next_arg_index = 0; | 4331 | size_t next_arg_index = 0; |
| | 4332 | |
| 4294 | if (first_arg_ptr) { | 4333 | if (first_arg_ptr) { |
| 4295 | IrInstruction *first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr); | 4334 | IrInstruction *first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr); |
| 4296 | if (first_arg->type_entry->id == TypeTableEntryIdInvalid) | 4335 | if (first_arg->type_entry->id == TypeTableEntryIdInvalid) |
| ... | @@ -4304,9 +4343,6 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal | ... | @@ -4304,9 +4343,6 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal |
| 4304 | if (casted_arg->type_entry->id == TypeTableEntryIdInvalid) | 4343 | if (casted_arg->type_entry->id == TypeTableEntryIdInvalid) |
| 4305 | return ira->codegen->builtin_types.entry_invalid; | 4344 | return ira->codegen->builtin_types.entry_invalid; |
| 4306 | | 4345 | |
| 4307 | if (is_inline && !ir_resolve_const(ira, casted_arg)) | | |
| 4308 | return ira->codegen->builtin_types.entry_invalid; | | |
| 4309 | | | |
| 4310 | casted_args[next_arg_index] = casted_arg; | 4346 | casted_args[next_arg_index] = casted_arg; |
| 4311 | next_arg_index += 1; | 4347 | next_arg_index += 1; |
| 4312 | } | 4348 | } |
| ... | @@ -4326,9 +4362,6 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal | ... | @@ -4326,9 +4362,6 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal |
| 4326 | casted_arg = old_arg; | 4362 | casted_arg = old_arg; |
| 4327 | } | 4363 | } |
| 4328 | | 4364 | |
| 4329 | if (is_inline && !ir_resolve_const(ira, casted_arg)) | | |
| 4330 | return ira->codegen->builtin_types.entry_invalid; | | |
| 4331 | | | |
| 4332 | casted_args[next_arg_index] = casted_arg; | 4365 | casted_args[next_arg_index] = casted_arg; |
| 4333 | next_arg_index += 1; | 4366 | next_arg_index += 1; |
| 4334 | } | 4367 | } |
| ... | @@ -4339,25 +4372,13 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal | ... | @@ -4339,25 +4372,13 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal |
| 4339 | if (return_type->id == TypeTableEntryIdInvalid) | 4372 | if (return_type->id == TypeTableEntryIdInvalid) |
| 4340 | return ira->codegen->builtin_types.entry_invalid; | 4373 | return ira->codegen->builtin_types.entry_invalid; |
| 4341 | | 4374 | |
| 4342 | if (is_inline) { | | |
| 4343 | assert(call_param_count == fn_type_id->param_count); | | |
| 4344 | IrInstruction *result = ir_eval_fn(ira, &call_instruction->base, fn_entry, casted_args); | | |
| 4345 | if (result->type_entry->id == TypeTableEntryIdInvalid) | | |
| 4346 | return ira->codegen->builtin_types.entry_invalid; | | |
| 4347 | | | |
| 4348 | ConstExprValue *out_val = ir_build_const_from(ira, &call_instruction->base, | | |
| 4349 | result->static_value.depends_on_compile_var); | | |
| 4350 | *out_val = result->static_value; | | |
| 4351 | return ir_finish_anal(ira, return_type); | | |
| 4352 | } | | |
| 4353 | | | |
| 4354 | IrInstruction *new_call_instruction = ir_build_call_from(&ira->new_irb, &call_instruction->base, | 4375 | IrInstruction *new_call_instruction = ir_build_call_from(&ira->new_irb, &call_instruction->base, |
| 4355 | fn_entry, fn_ref, call_param_count, casted_args); | 4376 | fn_entry, fn_ref, call_param_count, casted_args); |
| 4356 | | 4377 | |
| 4357 | if (type_has_bits(return_type) && handle_is_ptr(return_type)) { | 4378 | if (type_has_bits(return_type) && handle_is_ptr(return_type)) { |
| 4358 | FnTableEntry *owner_fn = exec_fn_entry(ira->new_irb.exec); | 4379 | FnTableEntry *callsite_fn = exec_fn_entry(ira->new_irb.exec); |
| 4359 | assert(owner_fn); | 4380 | assert(callsite_fn); |
| 4360 | owner_fn->alloca_list.append(new_call_instruction); | 4381 | callsite_fn->alloca_list.append(new_call_instruction); |
| 4361 | } | 4382 | } |
| 4362 | | 4383 | |
| 4363 | return ir_finish_anal(ira, return_type); | 4384 | return ir_finish_anal(ira, return_type); |
| ... | @@ -5349,7 +5370,7 @@ static TypeTableEntry *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructi | ... | @@ -5349,7 +5370,7 @@ static TypeTableEntry *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructi |
| 5349 | case TypeTableEntryIdTypeDecl: | 5370 | case TypeTableEntryIdTypeDecl: |
| 5350 | { | 5371 | { |
| 5351 | ConstExprValue *out_val = ir_build_const_from(ira, &typeof_instruction->base, false); | 5372 | ConstExprValue *out_val = ir_build_const_from(ira, &typeof_instruction->base, false); |
| 5352 | // TODO depends_on_compile_var should be set based on whether the type of the expression | 5373 | // TODO depends_on_compile_var should be set based on whether the type of the expression |
| 5353 | // depends_on_compile_var. but we currently don't have a thing to tell us if the type of | 5374 | // depends_on_compile_var. but we currently don't have a thing to tell us if the type of |
| 5354 | // something depends on a compile var | 5375 | // something depends on a compile var |
| 5355 | out_val->data.x_type = type_entry; | 5376 | out_val->data.x_type = type_entry; |