| ... | @@ -1165,7 +1165,12 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, AstNode *node, LValPurpose l | ... | @@ -1165,7 +1165,12 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, AstNode *node, LValPurpose l |
| 1165 | | 1165 | |
| 1166 | auto primitive_table_entry = irb->codegen->primitive_type_table.maybe_get(variable_name); | 1166 | auto primitive_table_entry = irb->codegen->primitive_type_table.maybe_get(variable_name); |
| 1167 | if (primitive_table_entry) { | 1167 | if (primitive_table_entry) { |
| 1168 | return ir_build_const_type(irb, node, primitive_table_entry->value); | 1168 | IrInstruction *value = ir_build_const_type(irb, node, primitive_table_entry->value); |
| | 1169 | if (lval == LValPurposeAddressOf) { |
| | 1170 | return ir_build_un_op(irb, node, IrUnOpAddressOf, value); |
| | 1171 | } else { |
| | 1172 | return value; |
| | 1173 | } |
| 1169 | } | 1174 | } |
| 1170 | | 1175 | |
| 1171 | VariableTableEntry *var = find_variable(irb->codegen, node->block_context, variable_name); | 1176 | VariableTableEntry *var = find_variable(irb->codegen, node->block_context, variable_name); |
| ... | @@ -1179,7 +1184,11 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, AstNode *node, LValPurpose l | ... | @@ -1179,7 +1184,11 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, AstNode *node, LValPurpose l |
| 1179 | | 1184 | |
| 1180 | AstNode *decl_node = find_decl(node->block_context, variable_name); | 1185 | AstNode *decl_node = find_decl(node->block_context, variable_name); |
| 1181 | if (decl_node) { | 1186 | if (decl_node) { |
| 1182 | return ir_gen_decl_ref(irb, node, decl_node, lval, node->block_context); | 1187 | IrInstruction *value = ir_gen_decl_ref(irb, node, decl_node, lval, node->block_context); |
| | 1188 | if (lval == LValPurposeAddressOf) |
| | 1189 | return ir_build_un_op(irb, node, IrUnOpAddressOf, value); |
| | 1190 | else |
| | 1191 | return value; |
| 1183 | } | 1192 | } |
| 1184 | | 1193 | |
| 1185 | if (node->owner->any_imports_failed) { | 1194 | if (node->owner->any_imports_failed) { |
| ... | @@ -1196,7 +1205,8 @@ static IrInstruction *ir_gen_array_access(IrBuilder *irb, AstNode *node, LValPur | ... | @@ -1196,7 +1205,8 @@ static IrInstruction *ir_gen_array_access(IrBuilder *irb, AstNode *node, LValPur |
| 1196 | assert(node->type == NodeTypeArrayAccessExpr); | 1205 | assert(node->type == NodeTypeArrayAccessExpr); |
| 1197 | | 1206 | |
| 1198 | AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr; | 1207 | AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr; |
| 1199 | IrInstruction *array_ref_instruction = ir_gen_node(irb, array_ref_node, node->block_context); | 1208 | IrInstruction *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, node->block_context, |
| | 1209 | LValPurposeAddressOf); |
| 1200 | if (array_ref_instruction == irb->codegen->invalid_instruction) | 1210 | if (array_ref_instruction == irb->codegen->invalid_instruction) |
| 1201 | return array_ref_instruction; | 1211 | return array_ref_instruction; |
| 1202 | | 1212 | |
| ... | @@ -1396,6 +1406,10 @@ static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, AstNode *node, Ir | ... | @@ -1396,6 +1406,10 @@ static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, AstNode *node, Ir |
| 1396 | if (value == irb->codegen->invalid_instruction) | 1406 | if (value == irb->codegen->invalid_instruction) |
| 1397 | return value; | 1407 | return value; |
| 1398 | | 1408 | |
| | 1409 | if (lval == LValPurposeAddressOf && (op_id == IrUnOpAddressOf || op_id == IrUnOpConstAddressOf)) { |
| | 1410 | return value; |
| | 1411 | } |
| | 1412 | |
| 1399 | return ir_build_un_op(irb, node, op_id, value); | 1413 | return ir_build_un_op(irb, node, op_id, value); |
| 1400 | } | 1414 | } |
| 1401 | | 1415 | |
| ... | @@ -1422,7 +1436,7 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, AstNode *node, LValP | ... | @@ -1422,7 +1436,7 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, AstNode *node, LValP |
| 1422 | case PrefixOpAddressOf: | 1436 | case PrefixOpAddressOf: |
| 1423 | return ir_gen_prefix_op_id_lval(irb, node, IrUnOpAddressOf, LValPurposeAddressOf); | 1437 | return ir_gen_prefix_op_id_lval(irb, node, IrUnOpAddressOf, LValPurposeAddressOf); |
| 1424 | case PrefixOpConstAddressOf: | 1438 | case PrefixOpConstAddressOf: |
| 1425 | return ir_gen_prefix_op_id_lval(irb, node, IrUnOpConstAddressOf, LValPurposeConstAddressOf); | 1439 | return ir_gen_prefix_op_id_lval(irb, node, IrUnOpConstAddressOf, LValPurposeAddressOf); |
| 1426 | case PrefixOpDereference: | 1440 | case PrefixOpDereference: |
| 1427 | return ir_gen_prefix_op_id_lval(irb, node, IrUnOpDereference, lval); | 1441 | return ir_gen_prefix_op_id_lval(irb, node, IrUnOpDereference, lval); |
| 1428 | case PrefixOpMaybe: | 1442 | case PrefixOpMaybe: |
| ... | @@ -2972,11 +2986,14 @@ static TypeTableEntry *ir_analyze_instruction_bin_op(IrAnalyze *ira, IrInstructi | ... | @@ -2972,11 +2986,14 @@ static TypeTableEntry *ir_analyze_instruction_bin_op(IrAnalyze *ira, IrInstructi |
| 2972 | } | 2986 | } |
| 2973 | | 2987 | |
| 2974 | static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstructionDeclVar *decl_var_instruction) { | 2988 | static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstructionDeclVar *decl_var_instruction) { |
| | 2989 | VariableTableEntry *var = decl_var_instruction->var; |
| | 2990 | |
| 2975 | IrInstruction *init_value = decl_var_instruction->init_value->other; | 2991 | IrInstruction *init_value = decl_var_instruction->init_value->other; |
| 2976 | if (init_value->type_entry->id == TypeTableEntryIdInvalid) | 2992 | if (init_value->type_entry->id == TypeTableEntryIdInvalid) { |
| 2977 | return init_value->type_entry; | 2993 | var->type = ira->codegen->builtin_types.entry_invalid; |
| | 2994 | return var->type; |
| | 2995 | } |
| 2978 | | 2996 | |
| 2979 | VariableTableEntry *var = decl_var_instruction->var; | | |
| 2980 | AstNodeVariableDeclaration *variable_declaration = &var->decl_node->data.variable_declaration; | 2997 | AstNodeVariableDeclaration *variable_declaration = &var->decl_node->data.variable_declaration; |
| 2981 | bool is_export = (variable_declaration->top_level_decl.visib_mod == VisibModExport); | 2998 | bool is_export = (variable_declaration->top_level_decl.visib_mod == VisibModExport); |
| 2982 | bool is_extern = variable_declaration->is_extern; | 2999 | bool is_extern = variable_declaration->is_extern; |
| ... | @@ -3522,6 +3539,7 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP | ... | @@ -3522,6 +3539,7 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP |
| 3522 | | 3539 | |
| 3523 | static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstructionVarPtr *var_ptr_instruction) { | 3540 | static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstructionVarPtr *var_ptr_instruction) { |
| 3524 | VariableTableEntry *var = var_ptr_instruction->var; | 3541 | VariableTableEntry *var = var_ptr_instruction->var; |
| | 3542 | assert(var->type); |
| 3525 | if (var->type->id == TypeTableEntryIdInvalid) | 3543 | if (var->type->id == TypeTableEntryIdInvalid) |
| 3526 | return var->type; | 3544 | return var->type; |
| 3527 | | 3545 | |
| ... | @@ -3561,7 +3579,12 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc | ... | @@ -3561,7 +3579,12 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc |
| 3561 | if (elem_index->type_entry->id == TypeTableEntryIdInvalid) | 3579 | if (elem_index->type_entry->id == TypeTableEntryIdInvalid) |
| 3562 | return ira->codegen->builtin_types.entry_invalid; | 3580 | return ira->codegen->builtin_types.entry_invalid; |
| 3563 | | 3581 | |
| 3564 | TypeTableEntry *array_type = array_ptr->type_entry; | 3582 | // This will be a pointer type because elem ptr IR instruction operates on a pointer to a thing. |
| | 3583 | TypeTableEntry *ptr_type = array_ptr->type_entry; |
| | 3584 | assert(ptr_type->id == TypeTableEntryIdPointer); |
| | 3585 | |
| | 3586 | TypeTableEntry *array_type = ptr_type->data.pointer.child_type; |
| | 3587 | ConstExprValue *array_ptr_val = const_ptr_pointee(&array_ptr->static_value); |
| 3565 | TypeTableEntry *return_type; | 3588 | TypeTableEntry *return_type; |
| 3566 | | 3589 | |
| 3567 | if (array_type->id == TypeTableEntryIdInvalid) { | 3590 | if (array_type->id == TypeTableEntryIdInvalid) { |
| ... | @@ -3600,12 +3623,12 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc | ... | @@ -3600,12 +3623,12 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc |
| 3600 | } | 3623 | } |
| 3601 | } | 3624 | } |
| 3602 | | 3625 | |
| 3603 | if (array_ptr->static_value.special != ConstValSpecialRuntime) { | 3626 | if (array_ptr_val->special != ConstValSpecialRuntime) { |
| 3604 | bool depends_on_compile_var = array_ptr->static_value.depends_on_compile_var || | 3627 | bool depends_on_compile_var = array_ptr_val->depends_on_compile_var || |
| 3605 | casted_elem_index->static_value.depends_on_compile_var; | 3628 | casted_elem_index->static_value.depends_on_compile_var; |
| 3606 | ConstExprValue *out_val = ir_build_const_from(ira, &elem_ptr_instruction->base, depends_on_compile_var); | 3629 | ConstExprValue *out_val = ir_build_const_from(ira, &elem_ptr_instruction->base, depends_on_compile_var); |
| 3607 | if (array_type->id == TypeTableEntryIdPointer) { | 3630 | if (array_type->id == TypeTableEntryIdPointer) { |
| 3608 | size_t offset = array_ptr->static_value.data.x_ptr.index; | 3631 | size_t offset = array_ptr_val->data.x_ptr.index; |
| 3609 | size_t new_index; | 3632 | size_t new_index; |
| 3610 | size_t mem_size; | 3633 | size_t mem_size; |
| 3611 | size_t old_size; | 3634 | size_t old_size; |
| ... | @@ -3615,7 +3638,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc | ... | @@ -3615,7 +3638,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc |
| 3615 | old_size = 1; | 3638 | old_size = 1; |
| 3616 | } else { | 3639 | } else { |
| 3617 | new_index = offset + index; | 3640 | new_index = offset + index; |
| 3618 | mem_size = array_ptr->static_value.data.x_ptr.base_ptr->data.x_array.size; | 3641 | mem_size = array_ptr_val->data.x_ptr.base_ptr->data.x_array.size; |
| 3619 | old_size = mem_size - offset; | 3642 | old_size = mem_size - offset; |
| 3620 | } | 3643 | } |
| 3621 | if (new_index >= mem_size) { | 3644 | if (new_index >= mem_size) { |
| ... | @@ -3623,11 +3646,11 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc | ... | @@ -3623,11 +3646,11 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc |
| 3623 | buf_sprintf("index %" PRIu64 " outside pointer of size %" PRIu64, index, old_size)); | 3646 | buf_sprintf("index %" PRIu64 " outside pointer of size %" PRIu64, index, old_size)); |
| 3624 | return ira->codegen->builtin_types.entry_invalid; | 3647 | return ira->codegen->builtin_types.entry_invalid; |
| 3625 | } | 3648 | } |
| 3626 | out_val->data.x_ptr.base_ptr = array_ptr->static_value.data.x_ptr.base_ptr; | 3649 | out_val->data.x_ptr.base_ptr = array_ptr_val->data.x_ptr.base_ptr; |
| 3627 | out_val->data.x_ptr.index = new_index; | 3650 | out_val->data.x_ptr.index = new_index; |
| 3628 | } else if (is_slice(array_type)) { | 3651 | } else if (is_slice(array_type)) { |
| 3629 | ConstExprValue *ptr_field = &array_ptr->static_value.data.x_struct.fields[slice_ptr_index]; | 3652 | ConstExprValue *ptr_field = &array_ptr_val->data.x_struct.fields[slice_ptr_index]; |
| 3630 | ConstExprValue *len_field = &array_ptr->static_value.data.x_struct.fields[slice_len_index]; | 3653 | ConstExprValue *len_field = &array_ptr_val->data.x_struct.fields[slice_len_index]; |
| 3631 | uint64_t slice_len = len_field->data.x_bignum.data.x_uint; | 3654 | uint64_t slice_len = len_field->data.x_bignum.data.x_uint; |
| 3632 | if (index >= slice_len) { | 3655 | if (index >= slice_len) { |
| 3633 | add_node_error(ira->codegen, elem_ptr_instruction->base.source_node, | 3656 | add_node_error(ira->codegen, elem_ptr_instruction->base.source_node, |
| ... | @@ -3645,7 +3668,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc | ... | @@ -3645,7 +3668,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc |
| 3645 | out_val->data.x_ptr.index = new_index; | 3668 | out_val->data.x_ptr.index = new_index; |
| 3646 | } | 3669 | } |
| 3647 | } else if (array_type->id == TypeTableEntryIdArray) { | 3670 | } else if (array_type->id == TypeTableEntryIdArray) { |
| 3648 | out_val->data.x_ptr.base_ptr = &array_ptr->static_value; | 3671 | out_val->data.x_ptr.base_ptr = array_ptr_val; |
| 3649 | out_val->data.x_ptr.index = index; | 3672 | out_val->data.x_ptr.index = index; |
| 3650 | } else { | 3673 | } else { |
| 3651 | zig_unreachable(); | 3674 | zig_unreachable(); |