diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/analyze.cpp | 30 | ||||
| -rw-r--r-- | src/codegen.cpp | 30 |
2 files changed, 51 insertions, 9 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp index 9fa5409c1e..fe943ec698 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -233,8 +233,7 @@ static TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) { } } -static TypeTableEntry *get_array_type(CodeGen *g, ImportTableEntry *import, - TypeTableEntry *child_type, uint64_t array_size) +static TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t array_size) { auto existing_entry = child_type->arrays_by_size.maybe_get(array_size); if (existing_entry) { @@ -1389,6 +1388,29 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry } } return container_type; + } else if (container_type->id == TypeTableEntryIdStruct && + container_type->data.structure.is_unknown_size_array && + kind == ContainerInitKindArray) + { + int elem_count = container_init_expr->entries.length; + + TypeTableEntry *pointer_type = container_type->data.structure.fields[0].type_entry; + assert(pointer_type->id == TypeTableEntryIdPointer); + TypeTableEntry *child_type = pointer_type->data.pointer.child_type; + + for (int i = 0; i < elem_count; i += 1) { + AstNode *elem_node = container_init_expr->entries.at(i); + analyze_expression(g, import, context, child_type, elem_node); + } + + TypeTableEntry *fixed_size_array_type = get_array_type(g, child_type, elem_count); + + StructValExprCodeGen *codegen = &container_init_expr->resolved_struct_val_expr; + codegen->type_entry = fixed_size_array_type; + codegen->source_node = node; + context->struct_val_expr_alloca_list.append(codegen); + + return fixed_size_array_type; } else if (container_type->id == TypeTableEntryIdArray) { zig_panic("TODO array container init"); return container_type; @@ -2151,7 +2173,7 @@ static TypeTableEntry *analyze_array_type(CodeGen *g, ImportTableEntry *import, ConstExprValue *const_val = &get_resolved_expr(size_node)->const_val; if (const_val->ok) { return resolve_expr_const_val_as_type(g, node, - get_array_type(g, import, child_type, const_val->data.x_uint)); + get_array_type(g, child_type, const_val->data.x_uint)); } else { add_node_error(g, size_node, buf_create_from_str("unable to resolve constant expression")); return g->builtin_types.entry_invalid; @@ -2986,7 +3008,7 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import, if (node->data.string_literal.c) { return_type = g->builtin_types.entry_c_string_literal; } else { - return_type = get_array_type(g, import, g->builtin_types.entry_u8, + return_type = get_array_type(g, g->builtin_types.entry_u8, buf_len(&node->data.string_literal.buf)); } break; diff --git a/src/codegen.cpp b/src/codegen.cpp index d9d22d52ac..fd5f048ffe 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1132,7 +1132,8 @@ static LLVMValueRef gen_struct_memcpy(CodeGen *g, AstNode *source_node, LLVMValu { assert(type_entry->id == TypeTableEntryIdStruct || type_entry->id == TypeTableEntryIdMaybe || - (type_entry->id == TypeTableEntryIdEnum && type_entry->data.enumeration.gen_field_count != 0)); + (type_entry->id == TypeTableEntryIdEnum && type_entry->data.enumeration.gen_field_count != 0) || + type_entry->id == TypeTableEntryIdArray); LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0); @@ -1157,11 +1158,9 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, AstNode *source_node, BinOpType b { if (op1_type->id == TypeTableEntryIdStruct || (op1_type->id == TypeTableEntryIdEnum && op1_type->data.enumeration.gen_field_count != 0) || - op1_type->id == TypeTableEntryIdMaybe) + op1_type->id == TypeTableEntryIdMaybe || + op1_type->id == TypeTableEntryIdArray) { - assert(op2_type->id == TypeTableEntryIdStruct || - (op2_type->id == TypeTableEntryIdEnum && op2_type->data.enumeration.gen_field_count != 0) || - op2_type->id == TypeTableEntryIdMaybe); assert(op1_type == op2_type); assert(bin_op == BinOpTypeAssign); @@ -1633,6 +1632,27 @@ static LLVMValueRef gen_container_init_expr(CodeGen *g, AstNode *node) { } else if (type_entry->id == TypeTableEntryIdVoid) { assert(node->data.container_init_expr.entries.length == 0); return nullptr; + } else if (type_entry->id == TypeTableEntryIdArray) { + StructValExprCodeGen *struct_val_expr_node = &node->data.container_init_expr.resolved_struct_val_expr; + LLVMValueRef tmp_array_ptr = struct_val_expr_node->ptr; + + int field_count = type_entry->data.array.len; + assert(field_count == node->data.container_init_expr.entries.length); + + for (int i = 0; i < field_count; i += 1) { + AstNode *field_node = node->data.container_init_expr.entries.at(i); + LLVMValueRef elem_val = gen_expr(g, field_node); + + LLVMValueRef indices[] = { + LLVMConstNull(g->builtin_types.entry_usize->type_ref), + LLVMConstInt(g->builtin_types.entry_usize->type_ref, i, false), + }; + add_debug_source_node(g, field_node); + LLVMValueRef elem_ptr = LLVMBuildInBoundsGEP(g->builder, tmp_array_ptr, indices, 2, ""); + LLVMBuildStore(g->builder, elem_val, elem_ptr); + } + + return tmp_array_ptr; } else { zig_unreachable(); } |
