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