| ... | @@ -1399,17 +1399,23 @@ static IrInstruction *ir_build_array_len(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -1399,17 +1399,23 @@ static IrInstruction *ir_build_array_len(IrBuilder *irb, Scope *scope, AstNode * |
| 1399 | return &instruction->base; | 1399 | return &instruction->base; |
| 1400 | } | 1400 | } |
| 1401 | | 1401 | |
| 1402 | static IrInstruction *ir_build_ref(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { | 1402 | static IrInstruction *ir_build_ref(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value, |
| | 1403 | bool is_const) |
| | 1404 | { |
| 1403 | IrInstructionRef *instruction = ir_build_instruction<IrInstructionRef>(irb, scope, source_node); | 1405 | IrInstructionRef *instruction = ir_build_instruction<IrInstructionRef>(irb, scope, source_node); |
| 1404 | instruction->value = value; | 1406 | instruction->value = value; |
| | 1407 | instruction->is_const = is_const; |
| 1405 | | 1408 | |
| 1406 | ir_ref_instruction(value); | 1409 | ir_ref_instruction(value); |
| 1407 | | 1410 | |
| 1408 | return &instruction->base; | 1411 | return &instruction->base; |
| 1409 | } | 1412 | } |
| 1410 | | 1413 | |
| 1411 | static IrInstruction *ir_build_ref_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction *value) { | 1414 | static IrInstruction *ir_build_ref_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction *value, |
| 1412 | IrInstruction *new_instruction = ir_build_ref(irb, old_instruction->scope, old_instruction->source_node, value); | 1415 | bool is_const) |
| | 1416 | { |
| | 1417 | IrInstruction *new_instruction = ir_build_ref(irb, old_instruction->scope, old_instruction->source_node, |
| | 1418 | value, is_const); |
| 1413 | ir_link_new_instruction(new_instruction, old_instruction); | 1419 | ir_link_new_instruction(new_instruction, old_instruction); |
| 1414 | return new_instruction; | 1420 | return new_instruction; |
| 1415 | } | 1421 | } |
| ... | @@ -2479,7 +2485,7 @@ static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, Tld | ... | @@ -2479,7 +2485,7 @@ static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, Tld |
| 2479 | assert(fn_entry->type_entry); | 2485 | assert(fn_entry->type_entry); |
| 2480 | IrInstruction *ref_instruction = ir_build_const_fn(irb, scope, source_node, fn_entry); | 2486 | IrInstruction *ref_instruction = ir_build_const_fn(irb, scope, source_node, fn_entry); |
| 2481 | if (lval != LValPurposeNone) | 2487 | if (lval != LValPurposeNone) |
| 2482 | return ir_build_ref(irb, scope, source_node, ref_instruction); | 2488 | return ir_build_ref(irb, scope, source_node, ref_instruction, true); |
| 2483 | else | 2489 | else |
| 2484 | return ref_instruction; | 2490 | return ref_instruction; |
| 2485 | } | 2491 | } |
| ... | @@ -2489,7 +2495,7 @@ static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, Tld | ... | @@ -2489,7 +2495,7 @@ static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, Tld |
| 2489 | TypeTableEntry *typedef_type = tld_typedef->type_entry; | 2495 | TypeTableEntry *typedef_type = tld_typedef->type_entry; |
| 2490 | IrInstruction *ref_instruction = ir_build_const_type(irb, scope, source_node, typedef_type); | 2496 | IrInstruction *ref_instruction = ir_build_const_type(irb, scope, source_node, typedef_type); |
| 2491 | if (lval != LValPurposeNone) | 2497 | if (lval != LValPurposeNone) |
| 2492 | return ir_build_ref(irb, scope, source_node, ref_instruction); | 2498 | return ir_build_ref(irb, scope, source_node, ref_instruction, true); |
| 2493 | else | 2499 | else |
| 2494 | return ref_instruction; | 2500 | return ref_instruction; |
| 2495 | } | 2501 | } |
| ... | @@ -2506,7 +2512,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, | ... | @@ -2506,7 +2512,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, |
| 2506 | if (primitive_table_entry) { | 2512 | if (primitive_table_entry) { |
| 2507 | IrInstruction *value = ir_build_const_type(irb, scope, node, primitive_table_entry->value); | 2513 | IrInstruction *value = ir_build_const_type(irb, scope, node, primitive_table_entry->value); |
| 2508 | if (lval != LValPurposeNone) { | 2514 | if (lval != LValPurposeNone) { |
| 2509 | return ir_build_ref(irb, scope, node, value); | 2515 | return ir_build_ref(irb, scope, node, value, lval == LValPurposeAddressOfConst); |
| 2510 | } else { | 2516 | } else { |
| 2511 | return value; | 2517 | return value; |
| 2512 | } | 2518 | } |
| ... | @@ -3105,14 +3111,15 @@ static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction * | ... | @@ -3105,14 +3111,15 @@ static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction * |
| 3105 | | 3111 | |
| 3106 | // We needed a pointer to a value, but we got a value. So we create | 3112 | // We needed a pointer to a value, but we got a value. So we create |
| 3107 | // an instruction which just makes a const pointer of it. | 3113 | // an instruction which just makes a const pointer of it. |
| 3108 | return ir_build_ref(irb, scope, value->source_node, value); | 3114 | return ir_build_ref(irb, scope, value->source_node, value, true); |
| 3109 | } | 3115 | } |
| 3110 | | 3116 | |
| 3111 | static IrInstruction *ir_gen_address_of(IrBuilder *irb, Scope *scope, AstNode *node, bool is_const, LValPurpose lval) { | 3117 | static IrInstruction *ir_gen_address_of(IrBuilder *irb, Scope *scope, AstNode *node, bool is_const, LValPurpose lval) { |
| 3112 | assert(node->type == NodeTypePrefixOpExpr); | 3118 | assert(node->type == NodeTypePrefixOpExpr); |
| 3113 | AstNode *expr_node = node->data.prefix_op_expr.primary_expr; | 3119 | AstNode *expr_node = node->data.prefix_op_expr.primary_expr; |
| 3114 | | 3120 | |
| 3115 | IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, LValPurposeAddressOf); | 3121 | IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, |
| | 3122 | is_const ? LValPurposeAddressOfConst : LValPurposeAddressOf); |
| 3116 | if (value == irb->codegen->invalid_instruction) | 3123 | if (value == irb->codegen->invalid_instruction) |
| 3117 | return value; | 3124 | return value; |
| 3118 | | 3125 | |
| ... | @@ -5102,7 +5109,8 @@ static IrInstruction *ir_analyze_cast_ref(IrAnalyze *ira, IrInstruction *source_ | ... | @@ -5102,7 +5109,8 @@ static IrInstruction *ir_analyze_cast_ref(IrAnalyze *ira, IrInstruction *source_ |
| 5102 | IrInstructionLoadPtr *load_ptr_inst = (IrInstructionLoadPtr *)value; | 5109 | IrInstructionLoadPtr *load_ptr_inst = (IrInstructionLoadPtr *)value; |
| 5103 | return load_ptr_inst->ptr; | 5110 | return load_ptr_inst->ptr; |
| 5104 | } else { | 5111 | } else { |
| 5105 | IrInstruction *new_instruction = ir_build_ref(&ira->new_irb, source_instr->scope, source_instr->source_node, value); | 5112 | IrInstruction *new_instruction = ir_build_ref(&ira->new_irb, source_instr->scope, |
| | 5113 | source_instr->source_node, value, true); |
| 5106 | | 5114 | |
| 5107 | TypeTableEntry *child_type = wanted_type->data.pointer.child_type; | 5115 | TypeTableEntry *child_type = wanted_type->data.pointer.child_type; |
| 5108 | if (type_has_bits(child_type)) { | 5116 | if (type_has_bits(child_type)) { |
| ... | @@ -5454,7 +5462,9 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc | ... | @@ -5454,7 +5462,9 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc |
| 5454 | } | 5462 | } |
| 5455 | } | 5463 | } |
| 5456 | | 5464 | |
| 5457 | static TypeTableEntry *ir_analyze_ref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *value) { | 5465 | static TypeTableEntry *ir_analyze_ref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *value, |
| | 5466 | bool is_const) |
| | 5467 | { |
| 5458 | if (value->type_entry->id == TypeTableEntryIdInvalid) | 5468 | if (value->type_entry->id == TypeTableEntryIdInvalid) |
| 5459 | return ira->codegen->builtin_types.entry_invalid; | 5469 | return ira->codegen->builtin_types.entry_invalid; |
| 5460 | | 5470 | |
| ... | @@ -5462,15 +5472,14 @@ static TypeTableEntry *ir_analyze_ref(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -5462,15 +5472,14 @@ static TypeTableEntry *ir_analyze_ref(IrAnalyze *ira, IrInstruction *source_inst |
| 5462 | ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); | 5472 | ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); |
| 5463 | if (!val) | 5473 | if (!val) |
| 5464 | return ira->codegen->builtin_types.entry_invalid; | 5474 | return ira->codegen->builtin_types.entry_invalid; |
| 5465 | bool ptr_is_const = false; | | |
| 5466 | return ir_analyze_const_ptr(ira, source_instruction, val, value->type_entry, | 5475 | return ir_analyze_const_ptr(ira, source_instruction, val, value->type_entry, |
| 5467 | false, ConstPtrSpecialNone, ptr_is_const); | 5476 | false, ConstPtrSpecialNone, is_const); |
| 5468 | } | 5477 | } |
| 5469 | | 5478 | |
| 5470 | TypeTableEntry *ptr_type = get_pointer_to_type(ira->codegen, value->type_entry, true); | 5479 | TypeTableEntry *ptr_type = get_pointer_to_type(ira->codegen, value->type_entry, true); |
| 5471 | FnTableEntry *fn_entry = exec_fn_entry(ira->new_irb.exec); | 5480 | FnTableEntry *fn_entry = exec_fn_entry(ira->new_irb.exec); |
| 5472 | assert(fn_entry); | 5481 | assert(fn_entry); |
| 5473 | IrInstruction *new_instruction = ir_build_ref_from(&ira->new_irb, source_instruction, value); | 5482 | IrInstruction *new_instruction = ir_build_ref_from(&ira->new_irb, source_instruction, value, is_const); |
| 5474 | fn_entry->alloca_list.append(new_instruction); | 5483 | fn_entry->alloca_list.append(new_instruction); |
| 5475 | return ptr_type; | 5484 | return ptr_type; |
| 5476 | } | 5485 | } |
| ... | @@ -6986,7 +6995,7 @@ static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruc | ... | @@ -6986,7 +6995,7 @@ static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruc |
| 6986 | return ir_analyze_const_ptr(ira, instruction, mem_slot, var->type, false, ptr_special, var->src_is_const); | 6995 | return ir_analyze_const_ptr(ira, instruction, mem_slot, var->type, false, ptr_special, var->src_is_const); |
| 6987 | } else { | 6996 | } else { |
| 6988 | ir_build_var_ptr_from(&ira->new_irb, instruction, var); | 6997 | ir_build_var_ptr_from(&ira->new_irb, instruction, var); |
| 6989 | return get_pointer_to_type(ira->codegen, var->type, false); | 6998 | return get_pointer_to_type(ira->codegen, var->type, var->src_is_const); |
| 6990 | } | 6999 | } |
| 6991 | } | 7000 | } |
| 6992 | | 7001 | |
| ... | @@ -7130,7 +7139,7 @@ static TypeTableEntry *ir_analyze_container_member_access_inner(IrAnalyze *ira, | ... | @@ -7130,7 +7139,7 @@ static TypeTableEntry *ir_analyze_container_member_access_inner(IrAnalyze *ira, |
| 7130 | bool depends_on_compile_var = container_ptr->static_value.depends_on_compile_var; | 7139 | bool depends_on_compile_var = container_ptr->static_value.depends_on_compile_var; |
| 7131 | IrInstruction *bound_fn_value = ir_build_const_bound_fn(&ira->new_irb, field_ptr_instruction->base.scope, | 7140 | IrInstruction *bound_fn_value = ir_build_const_bound_fn(&ira->new_irb, field_ptr_instruction->base.scope, |
| 7132 | field_ptr_instruction->base.source_node, fn_entry, container_ptr, depends_on_compile_var); | 7141 | field_ptr_instruction->base.source_node, fn_entry, container_ptr, depends_on_compile_var); |
| 7133 | return ir_analyze_ref(ira, &field_ptr_instruction->base, bound_fn_value); | 7142 | return ir_analyze_ref(ira, &field_ptr_instruction->base, bound_fn_value, true); |
| 7134 | } | 7143 | } |
| 7135 | } | 7144 | } |
| 7136 | ir_add_error_node(ira, field_ptr_instruction->base.source_node, | 7145 | ir_add_error_node(ira, field_ptr_instruction->base.source_node, |
| ... | @@ -8413,7 +8422,7 @@ static TypeTableEntry *ir_analyze_instruction_array_len(IrAnalyze *ira, | ... | @@ -8413,7 +8422,7 @@ static TypeTableEntry *ir_analyze_instruction_array_len(IrAnalyze *ira, |
| 8413 | | 8422 | |
| 8414 | static TypeTableEntry *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstructionRef *ref_instruction) { | 8423 | static TypeTableEntry *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstructionRef *ref_instruction) { |
| 8415 | IrInstruction *value = ref_instruction->value->other; | 8424 | IrInstruction *value = ref_instruction->value->other; |
| 8416 | return ir_analyze_ref(ira, &ref_instruction->base, value); | 8425 | return ir_analyze_ref(ira, &ref_instruction->base, value, ref_instruction->is_const); |
| 8417 | } | 8426 | } |
| 8418 | | 8427 | |
| 8419 | static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruction *instruction, | 8428 | static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruction *instruction, |