| ... | ... | @@ -176,7 +176,7 @@ static TypeTableEntry *get_int_type_unsigned(CodeGen *g, uint64_t x) { |
| 176 | 176 | |
| 177 | 177 | static TypeTableEntry *get_meta_type(CodeGen *g, TypeTableEntry *child_type) { |
| 178 | 178 | if (child_type->meta_parent) { |
| 179 | | return child_type->maybe_parent; |
| 179 | return child_type->meta_parent; |
| 180 | 180 | } else { |
| 181 | 181 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdMetaType); |
| 182 | 182 | buf_resize(&entry->name, 0); |
| ... | ... | @@ -705,7 +705,7 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt |
| 705 | 705 | |
| 706 | 706 | assert(enum_type->di_type); |
| 707 | 707 | |
| 708 | | int field_count = decl_node->data.struct_decl.fields.length; |
| 708 | uint32_t field_count = decl_node->data.struct_decl.fields.length; |
| 709 | 709 | |
| 710 | 710 | enum_type->data.enumeration.field_count = field_count; |
| 711 | 711 | enum_type->data.enumeration.fields = allocate<TypeEnumField>(field_count); |
| ... | ... | @@ -723,12 +723,13 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt |
| 723 | 723 | enum_type->data.enumeration.embedded_in_current = true; |
| 724 | 724 | |
| 725 | 725 | int gen_field_index = 0; |
| 726 | | for (int i = 0; i < field_count; i += 1) { |
| 726 | for (uint32_t i = 0; i < field_count; i += 1) { |
| 727 | 727 | AstNode *field_node = decl_node->data.struct_decl.fields.at(i); |
| 728 | 728 | TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i]; |
| 729 | 729 | type_enum_field->name = &field_node->data.struct_field.name; |
| 730 | 730 | type_enum_field->type_entry = resolve_type(g, field_node->data.struct_field.type, |
| 731 | 731 | import, import->block_context, false); |
| 732 | type_enum_field->value = i; |
| 732 | 733 | |
| 733 | 734 | di_enumerators[i] = LLVMZigCreateDebugEnumerator(g->dbuilder, buf_ptr(type_enum_field->name), i); |
| 734 | 735 | |
| ... | ... | @@ -1496,6 +1497,16 @@ TypeTableEntry *find_container(BlockContext *context, Buf *name) { |
| 1496 | 1497 | return nullptr; |
| 1497 | 1498 | } |
| 1498 | 1499 | |
| 1500 | static TypeEnumField *get_enum_field(TypeTableEntry *enum_type, Buf *name) { |
| 1501 | for (int i = 0; i < enum_type->data.enumeration.field_count; i += 1) { |
| 1502 | TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i]; |
| 1503 | if (buf_eql_buf(type_enum_field->name, name)) { |
| 1504 | return type_enum_field; |
| 1505 | } |
| 1506 | } |
| 1507 | return nullptr; |
| 1508 | } |
| 1509 | |
| 1499 | 1510 | static TypeStructField *get_struct_field(TypeTableEntry *struct_type, Buf *name) { |
| 1500 | 1511 | for (int i = 0; i < struct_type->data.structure.field_count; i += 1) { |
| 1501 | 1512 | TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; |
| ... | ... | @@ -1506,13 +1517,46 @@ static TypeStructField *get_struct_field(TypeTableEntry *struct_type, Buf *name) |
| 1506 | 1517 | return nullptr; |
| 1507 | 1518 | } |
| 1508 | 1519 | |
| 1520 | static TypeTableEntry *analyze_enum_value_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| 1521 | AstNode *field_access_node, AstNode *value_node, TypeTableEntry *enum_type, Buf *field_name) |
| 1522 | { |
| 1523 | TypeEnumField *type_enum_field = get_enum_field(enum_type, field_name); |
| 1524 | field_access_node->data.field_access_expr.type_enum_field = type_enum_field; |
| 1525 | if (type_enum_field) { |
| 1526 | if (value_node) { |
| 1527 | if (type_enum_field->type_entry->id == TypeTableEntryIdVoid) { |
| 1528 | add_node_error(g, field_access_node, |
| 1529 | buf_sprintf("enum value '%s.%s' has void parameter", |
| 1530 | buf_ptr(&enum_type->name), |
| 1531 | buf_ptr(field_name))); |
| 1532 | |
| 1533 | } else { |
| 1534 | analyze_expression(g, import, context, type_enum_field->type_entry, value_node); |
| 1535 | } |
| 1536 | } else if (type_enum_field->type_entry->id == TypeTableEntryIdVoid) { |
| 1537 | // OK |
| 1538 | } else { |
| 1539 | add_node_error(g, field_access_node, |
| 1540 | buf_sprintf("enum value '%s.%s' requires parameter of type '%s'", |
| 1541 | buf_ptr(&enum_type->name), |
| 1542 | buf_ptr(field_name), |
| 1543 | buf_ptr(&type_enum_field->type_entry->name))); |
| 1544 | } |
| 1545 | } else { |
| 1546 | add_node_error(g, field_access_node, |
| 1547 | buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), |
| 1548 | buf_ptr(&enum_type->name))); |
| 1549 | } |
| 1550 | return enum_type; |
| 1551 | } |
| 1552 | |
| 1509 | 1553 | static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| 1510 | 1554 | AstNode *node) |
| 1511 | 1555 | { |
| 1512 | 1556 | assert(node->type == NodeTypeFieldAccessExpr); |
| 1513 | 1557 | |
| 1514 | | TypeTableEntry *struct_type = analyze_expression(g, import, context, nullptr, |
| 1515 | | node->data.field_access_expr.struct_expr); |
| 1558 | AstNode *struct_expr_node = node->data.field_access_expr.struct_expr; |
| 1559 | TypeTableEntry *struct_type = analyze_expression(g, import, context, nullptr, struct_expr_node); |
| 1516 | 1560 | |
| 1517 | 1561 | TypeTableEntry *return_type; |
| 1518 | 1562 | |
| ... | ... | @@ -1548,9 +1592,9 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i |
| 1548 | 1592 | } else if (struct_type->id == TypeTableEntryIdMetaType && |
| 1549 | 1593 | struct_type->data.meta_type.child_type->id == TypeTableEntryIdEnum) |
| 1550 | 1594 | { |
| 1551 | | //TypeTableEntry *enum_type = struct_type->data.meta_type.child_type; |
| 1552 | | |
| 1553 | | zig_panic("TODO enum field access"); |
| 1595 | TypeTableEntry *enum_type = struct_type->data.meta_type.child_type; |
| 1596 | Buf *field_name = &node->data.field_access_expr.field_name; |
| 1597 | return_type = analyze_enum_value_expr(g, import, context, node, nullptr, enum_type, field_name); |
| 1554 | 1598 | } else { |
| 1555 | 1599 | if (struct_type->id != TypeTableEntryIdInvalid) { |
| 1556 | 1600 | add_node_error(g, node, |