| ... | ... | @@ -34,6 +34,8 @@ static AstNode *first_executing_node(AstNode *node) { |
| 34 | 34 | return first_executing_node(node->data.field_access_expr.struct_expr); |
| 35 | 35 | case NodeTypeSwitchRange: |
| 36 | 36 | return first_executing_node(node->data.switch_range.start); |
| 37 | case NodeTypeContainerInitExpr: |
| 38 | return first_executing_node(node->data.container_init_expr.type); |
| 37 | 39 | case NodeTypeRoot: |
| 38 | 40 | case NodeTypeRootExportDecl: |
| 39 | 41 | case NodeTypeFnProto: |
| ... | ... | @@ -69,7 +71,6 @@ static AstNode *first_executing_node(AstNode *node) { |
| 69 | 71 | case NodeTypeForExpr: |
| 70 | 72 | case NodeTypeSwitchExpr: |
| 71 | 73 | case NodeTypeSwitchProng: |
| 72 | | case NodeTypeContainerInitExpr: |
| 73 | 74 | case NodeTypeArrayType: |
| 74 | 75 | return node; |
| 75 | 76 | } |
| ... | ... | @@ -303,7 +304,8 @@ static void unknown_size_array_type_common_init(CodeGen *g, TypeTableEntry *chil |
| 303 | 304 | entry->align_in_bits = g->pointer_size_bytes * 8; |
| 304 | 305 | entry->data.structure.is_packed = false; |
| 305 | 306 | entry->data.structure.is_unknown_size_array = true; |
| 306 | | entry->data.structure.field_count = element_count; |
| 307 | entry->data.structure.src_field_count = element_count; |
| 308 | entry->data.structure.gen_field_count = element_count; |
| 307 | 309 | entry->data.structure.fields = allocate<TypeStructField>(element_count); |
| 308 | 310 | entry->data.structure.fields[0].name = buf_create_from_str("ptr"); |
| 309 | 311 | entry->data.structure.fields[0].type_entry = pointer_type; |
| ... | ... | @@ -764,7 +766,7 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE |
| 764 | 766 | |
| 765 | 767 | int field_count = decl_node->data.struct_decl.fields.length; |
| 766 | 768 | |
| 767 | | struct_type->data.structure.field_count = field_count; |
| 769 | struct_type->data.structure.src_field_count = field_count; |
| 768 | 770 | struct_type->data.structure.fields = allocate<TypeStructField>(field_count); |
| 769 | 771 | |
| 770 | 772 | // we possibly allocate too much here since gen_field_count can be lower than field_count. |
| ... | ... | @@ -823,6 +825,8 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE |
| 823 | 825 | } |
| 824 | 826 | struct_type->data.structure.embedded_in_current = false; |
| 825 | 827 | |
| 828 | struct_type->data.structure.gen_field_count = gen_field_index; |
| 829 | |
| 826 | 830 | if (!struct_type->data.structure.is_invalid) { |
| 827 | 831 | |
| 828 | 832 | LLVMStructSetBody(struct_type->type_ref, element_types, gen_field_index, false); |
| ... | ... | @@ -1083,6 +1087,9 @@ static void add_global_const_expr(CodeGen *g, Expr *expr) { |
| 1083 | 1087 | } |
| 1084 | 1088 | |
| 1085 | 1089 | static bool num_lit_fits_in_other_type(CodeGen *g, AstNode *literal_node, TypeTableEntry *other_type) { |
| 1090 | if (other_type->id == TypeTableEntryIdInvalid) { |
| 1091 | return false; |
| 1092 | } |
| 1086 | 1093 | Expr *expr = get_resolved_expr(literal_node); |
| 1087 | 1094 | ConstExprValue *const_val = &expr->const_val; |
| 1088 | 1095 | assert(const_val->ok); |
| ... | ... | @@ -1438,16 +1445,6 @@ static TypeEnumField *get_enum_field(TypeTableEntry *enum_type, Buf *name) { |
| 1438 | 1445 | return nullptr; |
| 1439 | 1446 | } |
| 1440 | 1447 | |
| 1441 | | static TypeStructField *get_struct_field(TypeTableEntry *struct_type, Buf *name) { |
| 1442 | | for (uint32_t i = 0; i < struct_type->data.structure.field_count; i += 1) { |
| 1443 | | TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; |
| 1444 | | if (buf_eql_buf(type_struct_field->name, name)) { |
| 1445 | | return type_struct_field; |
| 1446 | | } |
| 1447 | | } |
| 1448 | | return nullptr; |
| 1449 | | } |
| 1450 | | |
| 1451 | 1448 | static TypeTableEntry *analyze_enum_value_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| 1452 | 1449 | AstNode *field_access_node, AstNode *value_node, TypeTableEntry *enum_type, Buf *field_name) |
| 1453 | 1450 | { |
| ... | ... | @@ -1484,12 +1481,11 @@ static TypeTableEntry *analyze_enum_value_expr(CodeGen *g, ImportTableEntry *imp |
| 1484 | 1481 | return enum_type; |
| 1485 | 1482 | } |
| 1486 | 1483 | |
| 1487 | | static TypeStructField *find_struct_type_field(TypeTableEntry *type_entry, Buf *name, int *index) { |
| 1484 | static TypeStructField *find_struct_type_field(TypeTableEntry *type_entry, Buf *name) { |
| 1488 | 1485 | assert(type_entry->id == TypeTableEntryIdStruct); |
| 1489 | | for (uint32_t i = 0; i < type_entry->data.structure.field_count; i += 1) { |
| 1486 | for (uint32_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) { |
| 1490 | 1487 | TypeStructField *field = &type_entry->data.structure.fields[i]; |
| 1491 | 1488 | if (buf_eql_buf(field->name, name)) { |
| 1492 | | *index = i; |
| 1493 | 1489 | return field; |
| 1494 | 1490 | } |
| 1495 | 1491 | } |
| ... | ... | @@ -1530,16 +1526,18 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry |
| 1530 | 1526 | |
| 1531 | 1527 | |
| 1532 | 1528 | int expr_field_count = container_init_expr->entries.length; |
| 1533 | | int actual_field_count = container_type->data.structure.field_count; |
| 1529 | int actual_field_count = container_type->data.structure.src_field_count; |
| 1534 | 1530 | |
| 1535 | 1531 | int *field_use_counts = allocate<int>(actual_field_count); |
| 1532 | ConstExprValue *const_val = &get_resolved_expr(node)->const_val; |
| 1533 | const_val->ok = true; |
| 1534 | const_val->data.x_struct.fields = allocate<ConstExprValue*>(actual_field_count); |
| 1536 | 1535 | for (int i = 0; i < expr_field_count; i += 1) { |
| 1537 | 1536 | AstNode *val_field_node = container_init_expr->entries.at(i); |
| 1538 | 1537 | assert(val_field_node->type == NodeTypeStructValueField); |
| 1539 | 1538 | |
| 1540 | | int field_index; |
| 1541 | 1539 | TypeStructField *type_field = find_struct_type_field(container_type, |
| 1542 | | &val_field_node->data.struct_val_field.name, &field_index); |
| 1540 | &val_field_node->data.struct_val_field.name); |
| 1543 | 1541 | |
| 1544 | 1542 | if (!type_field) { |
| 1545 | 1543 | add_node_error(g, val_field_node, |
| ... | ... | @@ -1548,6 +1546,7 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry |
| 1548 | 1546 | continue; |
| 1549 | 1547 | } |
| 1550 | 1548 | |
| 1549 | int field_index = type_field->src_index; |
| 1551 | 1550 | field_use_counts[field_index] += 1; |
| 1552 | 1551 | if (field_use_counts[field_index] > 1) { |
| 1553 | 1552 | add_node_error(g, val_field_node, buf_sprintf("duplicate field")); |
| ... | ... | @@ -1558,6 +1557,16 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry |
| 1558 | 1557 | |
| 1559 | 1558 | analyze_expression(g, import, context, type_field->type_entry, |
| 1560 | 1559 | val_field_node->data.struct_val_field.expr); |
| 1560 | |
| 1561 | if (const_val->ok) { |
| 1562 | ConstExprValue *field_val = |
| 1563 | &get_resolved_expr(val_field_node->data.struct_val_field.expr)->const_val; |
| 1564 | if (field_val->ok) { |
| 1565 | const_val->data.x_struct.fields[field_index] = field_val; |
| 1566 | } else { |
| 1567 | const_val->ok = false; |
| 1568 | } |
| 1569 | } |
| 1561 | 1570 | } |
| 1562 | 1571 | |
| 1563 | 1572 | for (int i = 0; i < actual_field_count; i += 1) { |
| ... | ... | @@ -1634,7 +1643,7 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i |
| 1634 | 1643 | TypeTableEntry *bare_struct_type = (struct_type->id == TypeTableEntryIdStruct) ? |
| 1635 | 1644 | struct_type : struct_type->data.pointer.child_type; |
| 1636 | 1645 | |
| 1637 | | node->data.field_access_expr.type_struct_field = get_struct_field(bare_struct_type, field_name); |
| 1646 | node->data.field_access_expr.type_struct_field = find_struct_type_field(bare_struct_type, field_name); |
| 1638 | 1647 | if (node->data.field_access_expr.type_struct_field) { |
| 1639 | 1648 | return node->data.field_access_expr.type_struct_field->type_entry; |
| 1640 | 1649 | } else { |