authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-02-26 23:50:04-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-02-26 23:50:04-05:00
log25761570f1bb4413020ebbfc959caa3429453517
treeac228c95e0393a8b36202864c60a4fd712a0e8d3
parent8dd0b4e1f12bc9f70ff6c312b35563595fdb4476

more robust const struct values


4 files changed, 63 insertions(+), 9 deletions(-)

src/analyze.cpp+22-4
...@@ -3485,10 +3485,11 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {...@@ -3485,10 +3485,11 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {
3485 ConstExprValue *element_val = &const_val->data.x_array.elements[i];3485 ConstExprValue *element_val = &const_val->data.x_array.elements[i];
3486 element_val->type = canon_wanted_type->data.array.child_type;3486 element_val->type = canon_wanted_type->data.array.child_type;
3487 init_const_undefined(g, element_val);3487 init_const_undefined(g, element_val);
3488 if (get_underlying_type(element_val->type)->id == TypeTableEntryIdArray) {3488 ConstParent *parent = get_const_val_parent(element_val);
3489 element_val->data.x_array.parent.id = ConstParentIdArray;3489 if (parent != nullptr) {
3490 element_val->data.x_array.parent.data.p_array.array_val = const_val;3490 parent->id = ConstParentIdArray;
3491 element_val->data.x_array.parent.data.p_array.elem_index = i;3491 parent->data.p_array.array_val = const_val;
3492 parent->data.p_array.elem_index = i;
3492 }3493 }
3493 }3494 }
3494 } else if (canon_wanted_type->id == TypeTableEntryIdStruct) {3495 } else if (canon_wanted_type->id == TypeTableEntryIdStruct) {
...@@ -3502,6 +3503,12 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {...@@ -3502,6 +3503,12 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {
3502 field_val->type = canon_wanted_type->data.structure.fields[i].type_entry;3503 field_val->type = canon_wanted_type->data.structure.fields[i].type_entry;
3503 assert(field_val->type);3504 assert(field_val->type);
3504 init_const_undefined(g, field_val);3505 init_const_undefined(g, field_val);
3506 ConstParent *parent = get_const_val_parent(field_val);
3507 if (parent != nullptr) {
3508 parent->id = ConstParentIdStruct;
3509 parent->data.p_struct.struct_val = const_val;
3510 parent->data.p_struct.field_index = i;
3511 }
3505 }3512 }
3506 } else {3513 } else {
3507 const_val->special = ConstValSpecialUndef;3514 const_val->special = ConstValSpecialUndef;
...@@ -4068,3 +4075,14 @@ bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) {...@@ -4068,3 +4075,14 @@ bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) {
4068 }4075 }
4069 zig_unreachable();4076 zig_unreachable();
4070}4077}
4078
4079ConstParent *get_const_val_parent(ConstExprValue *value) {
4080 assert(value->type);
4081 TypeTableEntry *canon_type = get_underlying_type(value->type);
4082 if (canon_type->id == TypeTableEntryIdArray) {
4083 return &value->data.x_array.parent;
4084 } else if (canon_type->id == TypeTableEntryIdStruct) {
4085 return &value->data.x_struct.parent;
4086 }
4087 return nullptr;
4088}
src/analyze.hpp+1
...@@ -147,5 +147,6 @@ ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_...@@ -147,5 +147,6 @@ ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_
147void init_const_undefined(CodeGen *g, ConstExprValue *const_val);147void init_const_undefined(CodeGen *g, ConstExprValue *const_val);
148148
149TypeTableEntry *make_int_type(CodeGen *g, bool is_signed, size_t size_in_bits);149TypeTableEntry *make_int_type(CodeGen *g, bool is_signed, size_t size_in_bits);
150ConstParent *get_const_val_parent(ConstExprValue *value);
150151
151#endif152#endif
src/ir.cpp+17-5
...@@ -10567,7 +10567,7 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru...@@ -10567,7 +10567,7 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru
10567 if (existing_assign_node) {10567 if (existing_assign_node) {
10568 ErrorMsg *msg = ir_add_error_node(ira, field->source_node, buf_sprintf("duplicate field"));10568 ErrorMsg *msg = ir_add_error_node(ira, field->source_node, buf_sprintf("duplicate field"));
10569 add_error_note(ira->codegen, msg, existing_assign_node, buf_sprintf("other field here"));10569 add_error_note(ira->codegen, msg, existing_assign_node, buf_sprintf("other field here"));
10570 continue;10570 return ira->codegen->builtin_types.entry_invalid;
10571 }10571 }
10572 field_assign_nodes[field_index] = field->source_node;10572 field_assign_nodes[field_index] = field->source_node;
1057310573
...@@ -10602,6 +10602,17 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru...@@ -10602,6 +10602,17 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru
10602 if (const_val.special == ConstValSpecialStatic) {10602 if (const_val.special == ConstValSpecialStatic) {
10603 ConstExprValue *out_val = ir_build_const_from(ira, instruction);10603 ConstExprValue *out_val = ir_build_const_from(ira, instruction);
10604 *out_val = const_val;10604 *out_val = const_val;
10605
10606 for (size_t i = 0; i < instr_field_count; i += 1) {
10607 ConstExprValue *field_val = &out_val->data.x_struct.fields[i];
10608 ConstParent *parent = get_const_val_parent(field_val);
10609 if (parent != nullptr) {
10610 parent->id = ConstParentIdStruct;
10611 parent->data.p_struct.field_index = i;
10612 parent->data.p_struct.struct_val = out_val;
10613 }
10614 }
10615
10605 return container_type;10616 return container_type;
10606 }10617 }
1060710618
...@@ -10681,10 +10692,11 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira...@@ -10681,10 +10692,11 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira
10681 *out_val = const_val;10692 *out_val = const_val;
10682 for (size_t i = 0; i < elem_count; i += 1) {10693 for (size_t i = 0; i < elem_count; i += 1) {
10683 ConstExprValue *elem_val = &out_val->data.x_array.elements[i];10694 ConstExprValue *elem_val = &out_val->data.x_array.elements[i];
10684 if (elem_val->type->id == TypeTableEntryIdArray) {10695 ConstParent *parent = get_const_val_parent(elem_val);
10685 elem_val->data.x_array.parent.id = ConstParentIdArray;10696 if (parent != nullptr) {
10686 elem_val->data.x_array.parent.data.p_array.array_val = out_val;10697 parent->id = ConstParentIdArray;
10687 elem_val->data.x_array.parent.data.p_array.elem_index = i;10698 parent->data.p_array.array_val = out_val;
10699 parent->data.p_array.elem_index = i;
10688 }10700 }
10689 }10701 }
10690 return fixed_size_array_type;10702 return fixed_size_array_type;
test/cases/array.zig+23
...@@ -70,3 +70,26 @@ fn nestedArrays() {...@@ -70,3 +70,26 @@ fn nestedArrays() {
70 if (i == 4) assert(mem.eql(u8, s, "thing"));70 if (i == 4) assert(mem.eql(u8, s, "thing"));
71 }71 }
72}72}
73
74
75// TODO
76//var s_array: [8]Sub = undefined;
77//const Sub = struct {
78// b: u8,
79//};
80//const Str = struct {
81// a: []Sub,
82//};
83//fn setGlobalVarArrayViaSliceEmbeddedInStruct() {
84// @setFnTest(this);
85//
86// var s = Str { .a = s_array[0...]};
87//
88// s.a[0].b = 1;
89// s.a[1].b = 2;
90// s.a[2].b = 3;
91//
92// assert(s_array[0].b == 1);
93// assert(s_array[1].b == 2);
94// assert(s_array[2].b == 3);
95//}