mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
more robust const struct values
This commit is contained in:
parent
8dd0b4e1f1
commit
25761570f1
@ -3485,10 +3485,11 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {
|
||||
ConstExprValue *element_val = &const_val->data.x_array.elements[i];
|
||||
element_val->type = canon_wanted_type->data.array.child_type;
|
||||
init_const_undefined(g, element_val);
|
||||
if (get_underlying_type(element_val->type)->id == TypeTableEntryIdArray) {
|
||||
element_val->data.x_array.parent.id = ConstParentIdArray;
|
||||
element_val->data.x_array.parent.data.p_array.array_val = const_val;
|
||||
element_val->data.x_array.parent.data.p_array.elem_index = i;
|
||||
ConstParent *parent = get_const_val_parent(element_val);
|
||||
if (parent != nullptr) {
|
||||
parent->id = ConstParentIdArray;
|
||||
parent->data.p_array.array_val = const_val;
|
||||
parent->data.p_array.elem_index = i;
|
||||
}
|
||||
}
|
||||
} else if (canon_wanted_type->id == TypeTableEntryIdStruct) {
|
||||
@ -3502,6 +3503,12 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {
|
||||
field_val->type = canon_wanted_type->data.structure.fields[i].type_entry;
|
||||
assert(field_val->type);
|
||||
init_const_undefined(g, field_val);
|
||||
ConstParent *parent = get_const_val_parent(field_val);
|
||||
if (parent != nullptr) {
|
||||
parent->id = ConstParentIdStruct;
|
||||
parent->data.p_struct.struct_val = const_val;
|
||||
parent->data.p_struct.field_index = i;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const_val->special = ConstValSpecialUndef;
|
||||
@ -4068,3 +4075,14 @@ bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) {
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
|
||||
ConstParent *get_const_val_parent(ConstExprValue *value) {
|
||||
assert(value->type);
|
||||
TypeTableEntry *canon_type = get_underlying_type(value->type);
|
||||
if (canon_type->id == TypeTableEntryIdArray) {
|
||||
return &value->data.x_array.parent;
|
||||
} else if (canon_type->id == TypeTableEntryIdStruct) {
|
||||
return &value->data.x_struct.parent;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -147,5 +147,6 @@ ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_
|
||||
void init_const_undefined(CodeGen *g, ConstExprValue *const_val);
|
||||
|
||||
TypeTableEntry *make_int_type(CodeGen *g, bool is_signed, size_t size_in_bits);
|
||||
ConstParent *get_const_val_parent(ConstExprValue *value);
|
||||
|
||||
#endif
|
||||
|
||||
22
src/ir.cpp
22
src/ir.cpp
@ -10567,7 +10567,7 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru
|
||||
if (existing_assign_node) {
|
||||
ErrorMsg *msg = ir_add_error_node(ira, field->source_node, buf_sprintf("duplicate field"));
|
||||
add_error_note(ira->codegen, msg, existing_assign_node, buf_sprintf("other field here"));
|
||||
continue;
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
}
|
||||
field_assign_nodes[field_index] = field->source_node;
|
||||
|
||||
@ -10602,6 +10602,17 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru
|
||||
if (const_val.special == ConstValSpecialStatic) {
|
||||
ConstExprValue *out_val = ir_build_const_from(ira, instruction);
|
||||
*out_val = const_val;
|
||||
|
||||
for (size_t i = 0; i < instr_field_count; i += 1) {
|
||||
ConstExprValue *field_val = &out_val->data.x_struct.fields[i];
|
||||
ConstParent *parent = get_const_val_parent(field_val);
|
||||
if (parent != nullptr) {
|
||||
parent->id = ConstParentIdStruct;
|
||||
parent->data.p_struct.field_index = i;
|
||||
parent->data.p_struct.struct_val = out_val;
|
||||
}
|
||||
}
|
||||
|
||||
return container_type;
|
||||
}
|
||||
|
||||
@ -10681,10 +10692,11 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira
|
||||
*out_val = const_val;
|
||||
for (size_t i = 0; i < elem_count; i += 1) {
|
||||
ConstExprValue *elem_val = &out_val->data.x_array.elements[i];
|
||||
if (elem_val->type->id == TypeTableEntryIdArray) {
|
||||
elem_val->data.x_array.parent.id = ConstParentIdArray;
|
||||
elem_val->data.x_array.parent.data.p_array.array_val = out_val;
|
||||
elem_val->data.x_array.parent.data.p_array.elem_index = i;
|
||||
ConstParent *parent = get_const_val_parent(elem_val);
|
||||
if (parent != nullptr) {
|
||||
parent->id = ConstParentIdArray;
|
||||
parent->data.p_array.array_val = out_val;
|
||||
parent->data.p_array.elem_index = i;
|
||||
}
|
||||
}
|
||||
return fixed_size_array_type;
|
||||
|
||||
@ -70,3 +70,26 @@ fn nestedArrays() {
|
||||
if (i == 4) assert(mem.eql(u8, s, "thing"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO
|
||||
//var s_array: [8]Sub = undefined;
|
||||
//const Sub = struct {
|
||||
// b: u8,
|
||||
//};
|
||||
//const Str = struct {
|
||||
// a: []Sub,
|
||||
//};
|
||||
//fn setGlobalVarArrayViaSliceEmbeddedInStruct() {
|
||||
// @setFnTest(this);
|
||||
//
|
||||
// var s = Str { .a = s_array[0...]};
|
||||
//
|
||||
// s.a[0].b = 1;
|
||||
// s.a[1].b = 2;
|
||||
// s.a[2].b = 3;
|
||||
//
|
||||
// assert(s_array[0].b == 1);
|
||||
// assert(s_array[1].b == 2);
|
||||
// assert(s_array[2].b == 3);
|
||||
//}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user