| ... | ... | @@ -25942,6 +25942,36 @@ static ZigType *get_const_field_meta_type_optional(IrAnalyze *ira, AstNode *sour |
| 25942 | 25942 | return value->data.x_optional->data.x_type; |
| 25943 | 25943 | } |
| 25944 | 25944 | |
| 25945 | static Error get_const_field_buf(IrAnalyze *ira, AstNode *source_node, ZigValue *struct_value, |
| 25946 | const char *name, size_t field_index, Buf *out) |
| 25947 | { |
| 25948 | ZigValue *slice = get_const_field(ira, source_node, struct_value, name, field_index); |
| 25949 | ZigValue *ptr = slice->data.x_struct.fields[slice_ptr_index]; |
| 25950 | ZigValue *len = slice->data.x_struct.fields[slice_len_index]; |
| 25951 | assert(ptr->data.x_ptr.special == ConstPtrSpecialBaseArray); |
| 25952 | assert(ptr->data.x_ptr.data.base_array.elem_index == 0); |
| 25953 | ZigValue *arr = ptr->data.x_ptr.data.base_array.array_val; |
| 25954 | assert(arr->special == ConstValSpecialStatic); |
| 25955 | switch (arr->data.x_array.special) { |
| 25956 | case ConstArraySpecialUndef: |
| 25957 | return ErrorSemanticAnalyzeFail; |
| 25958 | case ConstArraySpecialNone: { |
| 25959 | buf_resize(out, 0); |
| 25960 | size_t count = bigint_as_usize(&len->data.x_bigint); |
| 25961 | for (size_t j = 0; j < count; j++) { |
| 25962 | ZigValue *ch_val = &arr->data.x_array.data.s_none.elements[j]; |
| 25963 | unsigned ch = bigint_as_u32(&ch_val->data.x_bigint); |
| 25964 | buf_append_char(out, ch); |
| 25965 | } |
| 25966 | break; |
| 25967 | } |
| 25968 | case ConstArraySpecialBuf: |
| 25969 | buf_init_from_buf(out, arr->data.x_array.data.s_buf); |
| 25970 | break; |
| 25971 | } |
| 25972 | return ErrorNone; |
| 25973 | } |
| 25974 | |
| 25945 | 25975 | static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeId tagTypeId, ZigValue *payload) { |
| 25946 | 25976 | Error err; |
| 25947 | 25977 | switch (tagTypeId) { |
| ... | ... | @@ -26145,30 +26175,9 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI |
| 26145 | 26175 | assert(error->type == ir_type_info_get_type(ira, "Error", nullptr)); |
| 26146 | 26176 | ErrorTableEntry *err_entry = heap::c_allocator.create<ErrorTableEntry>(); |
| 26147 | 26177 | err_entry->decl_node = source_instr->source_node; |
| 26148 | | ZigValue *name_slice = get_const_field(ira, source_instr->source_node, error, "name", 0); |
| 26149 | | ZigValue *name_ptr = name_slice->data.x_struct.fields[slice_ptr_index]; |
| 26150 | | ZigValue *name_len = name_slice->data.x_struct.fields[slice_len_index]; |
| 26151 | | assert(name_ptr->data.x_ptr.special == ConstPtrSpecialBaseArray); |
| 26152 | | assert(name_ptr->data.x_ptr.data.base_array.elem_index == 0); |
| 26153 | | ZigValue *name_arr = name_ptr->data.x_ptr.data.base_array.array_val; |
| 26154 | | assert(name_arr->special == ConstValSpecialStatic); |
| 26155 | | switch (name_arr->data.x_array.special) { |
| 26156 | | case ConstArraySpecialUndef: |
| 26157 | | return ira->codegen->invalid_inst_gen->value->type; |
| 26158 | | case ConstArraySpecialNone: { |
| 26159 | | buf_resize(&err_entry->name, 0); |
| 26160 | | size_t name_count = bigint_as_usize(&name_len->data.x_bigint); |
| 26161 | | for (size_t j = 0; j < name_count; j++) { |
| 26162 | | ZigValue *ch_val = &name_arr->data.x_array.data.s_none.elements[j]; |
| 26163 | | unsigned ch = bigint_as_u32(&ch_val->data.x_bigint); |
| 26164 | | buf_append_char(&err_entry->name, ch); |
| 26165 | | } |
| 26166 | | break; |
| 26167 | | } |
| 26168 | | case ConstArraySpecialBuf: |
| 26169 | | buf_init_from_buf(&err_entry->name, name_arr->data.x_array.data.s_buf); |
| 26170 | | break; |
| 26171 | | } |
| 26178 | Error err; |
| 26179 | if ((err = get_const_field_buf(ira, source_instr->source_node, error, "name", 0, &err_entry->name))) |
| 26180 | return ira->codegen->invalid_inst_gen->value->type; |
| 26172 | 26181 | auto existing_entry = ira->codegen->error_table.put_unique(&err_entry->name, err_entry); |
| 26173 | 26182 | if (existing_entry) { |
| 26174 | 26183 | err_entry->value = existing_entry->value->value; |
| ... | ... | @@ -26188,14 +26197,92 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI |
| 26188 | 26197 | } |
| 26189 | 26198 | return err_set_type; |
| 26190 | 26199 | } |
| 26200 | case ZigTypeIdStruct: { |
| 26201 | assert(payload->special == ConstValSpecialStatic); |
| 26202 | assert(payload->type == ir_type_info_get_type(ira, "Struct", nullptr)); |
| 26203 | |
| 26204 | ZigValue *layout_value = get_const_field(ira, source_instr->source_node, payload, "layout", 0); |
| 26205 | assert(layout_value->special == ConstValSpecialStatic); |
| 26206 | assert(layout_value->type->id == ZigTypeIdEnum); |
| 26207 | ContainerLayout layout = (ContainerLayout)bigint_as_u32(&layout_value->data.x_enum_tag); |
| 26208 | |
| 26209 | ZigValue *fields_value = get_const_field(ira, source_instr->source_node, payload, "fields", 1); |
| 26210 | assert(fields_value->special == ConstValSpecialStatic); |
| 26211 | assert(is_slice(fields_value->type)); |
| 26212 | ZigValue *fields_ptr = fields_value->data.x_struct.fields[slice_ptr_index]; |
| 26213 | ZigValue *fields_len_value = fields_value->data.x_struct.fields[slice_len_index]; |
| 26214 | size_t fields_len = bigint_as_usize(&fields_len_value->data.x_bigint); |
| 26215 | |
| 26216 | ZigValue *decls_value = get_const_field(ira, source_instr->source_node, payload, "decls", 2); |
| 26217 | assert(decls_value->special == ConstValSpecialStatic); |
| 26218 | assert(is_slice(decls_value->type)); |
| 26219 | ZigValue *decls_len_value = decls_value->data.x_struct.fields[slice_len_index]; |
| 26220 | size_t decls_len = bigint_as_usize(&decls_len_value->data.x_bigint); |
| 26221 | if (decls_len != 0) { |
| 26222 | ir_add_error(ira, source_instr, buf_create_from_str("TypeInfo.Struct.decls must be empty for @Type")); |
| 26223 | return ira->codegen->invalid_inst_gen->value->type; |
| 26224 | } |
| 26225 | |
| 26226 | bool is_tuple; |
| 26227 | get_const_field_bool(ira, source_instr->source_node, payload, "is_tuple", 3, &is_tuple); |
| 26228 | |
| 26229 | ZigType *entry = new_type_table_entry(ZigTypeIdStruct); |
| 26230 | buf_init_from_buf(&entry->name, |
| 26231 | get_anon_type_name(ira->codegen, ira->old_irb.exec, "struct", source_instr->scope, source_instr->source_node, &entry->name)); |
| 26232 | entry->data.structure.decl_node = source_instr->source_node; |
| 26233 | entry->data.structure.fields = alloc_type_struct_fields(fields_len); |
| 26234 | entry->data.structure.fields_by_name.init(fields_len); |
| 26235 | entry->data.structure.src_field_count = fields_len; |
| 26236 | entry->data.structure.layout = layout; |
| 26237 | entry->data.structure.special = is_tuple ? StructSpecialInferredTuple : StructSpecialNone; |
| 26238 | entry->data.structure.created_by_at_type = true; |
| 26239 | entry->data.structure.decls_scope = create_decls_scope(ira->codegen, nullptr, nullptr, entry, entry, buf_create_from_str("a")); |
| 26240 | |
| 26241 | assert(fields_ptr->data.x_ptr.special == ConstPtrSpecialBaseArray); |
| 26242 | assert(fields_ptr->data.x_ptr.data.base_array.elem_index == 0); |
| 26243 | ZigValue *fields_arr = fields_ptr->data.x_ptr.data.base_array.array_val; |
| 26244 | assert(fields_arr->special == ConstValSpecialStatic); |
| 26245 | assert(fields_arr->data.x_array.special == ConstArraySpecialNone); |
| 26246 | for (size_t i = 0; i < fields_len; i++) { |
| 26247 | ZigValue *field_value = &fields_arr->data.x_array.data.s_none.elements[i]; |
| 26248 | assert(field_value->type->id == ZigTypeIdStruct); |
| 26249 | TypeStructField *field = entry->data.structure.fields[i]; |
| 26250 | field->name = buf_alloc(); |
| 26251 | if ((err = get_const_field_buf(ira, source_instr->source_node, field_value, "name", 0, field->name))) |
| 26252 | return ira->codegen->invalid_inst_gen->value->type; |
| 26253 | field->decl_node = source_instr->source_node; |
| 26254 | ZigValue *type_value = get_const_field(ira, source_instr->source_node, field_value, "field_type", 1); |
| 26255 | field->type_val = type_value; |
| 26256 | field->type_entry = type_value->data.x_type; |
| 26257 | if (entry->data.structure.fields_by_name.put_unique(field->name, field) != nullptr) { |
| 26258 | ir_add_error(ira, source_instr, buf_sprintf("duplicate struct field '%s'", buf_ptr(field->name))); |
| 26259 | return ira->codegen->invalid_inst_gen->value->type; |
| 26260 | } |
| 26261 | ZigValue *default_value = get_const_field(ira, source_instr->source_node, field_value, "default_value", 2); |
| 26262 | if (default_value->type->id == ZigTypeIdNull) { |
| 26263 | field->init_val = nullptr; |
| 26264 | } else if (default_value->type->id == ZigTypeIdOptional && default_value->type->data.maybe.child_type == field->type_entry) { |
| 26265 | field->init_val = default_value->data.x_optional; |
| 26266 | } else if (default_value->type == field->type_entry) { |
| 26267 | field->init_val = default_value; |
| 26268 | } else { |
| 26269 | ir_add_error(ira, source_instr, |
| 26270 | buf_sprintf("default_value of field '%s' is of type '%s', expected '%s' or '?%s'", |
| 26271 | buf_ptr(field->name), buf_ptr(&default_value->type->name), |
| 26272 | buf_ptr(&field->type_entry->name), buf_ptr(&field->type_entry->name))); |
| 26273 | return ira->codegen->invalid_inst_gen->value->type; |
| 26274 | } |
| 26275 | } |
| 26276 | |
| 26277 | return entry; |
| 26278 | } |
| 26191 | 26279 | case ZigTypeIdEnum: |
| 26280 | case ZigTypeIdUnion: |
| 26192 | 26281 | ir_add_error(ira, source_instr, buf_sprintf( |
| 26193 | 26282 | "TODO implement @Type for 'TypeInfo.%s': see https://github.com/ziglang/zig/issues/2907", type_id_name(tagTypeId))); |
| 26194 | 26283 | return ira->codegen->invalid_inst_gen->value->type; |
| 26195 | | case ZigTypeIdUnion: |
| 26196 | 26284 | case ZigTypeIdFn: |
| 26197 | 26285 | case ZigTypeIdBoundFn: |
| 26198 | | case ZigTypeIdStruct: |
| 26199 | 26286 | ir_add_error(ira, source_instr, buf_sprintf( |
| 26200 | 26287 | "@Type not available for 'TypeInfo.%s'", type_id_name(tagTypeId))); |
| 26201 | 26288 | return ira->codegen->invalid_inst_gen->value->type; |