| ... | ... | @@ -2110,7 +2110,8 @@ static TypeEnumField *get_enum_field(TypeTableEntry *enum_type, Buf *name) { |
| 2110 | 2110 | } |
| 2111 | 2111 | |
| 2112 | 2112 | static TypeTableEntry *analyze_enum_value_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| 2113 | | AstNode *field_access_node, AstNode *value_node, TypeTableEntry *enum_type, Buf *field_name) |
| 2113 | AstNode *field_access_node, AstNode *value_node, TypeTableEntry *enum_type, Buf *field_name, |
| 2114 | AstNode *out_node) |
| 2114 | 2115 | { |
| 2115 | 2116 | assert(field_access_node->type == NodeTypeFieldAccessExpr); |
| 2116 | 2117 | |
| ... | ... | @@ -2119,15 +2120,32 @@ static TypeTableEntry *analyze_enum_value_expr(CodeGen *g, ImportTableEntry *imp |
| 2119 | 2120 | |
| 2120 | 2121 | if (type_enum_field) { |
| 2121 | 2122 | if (value_node) { |
| 2122 | | analyze_expression(g, import, context, type_enum_field->type_entry, value_node); |
| 2123 | AstNode **value_node_ptr = value_node->parent_field; |
| 2124 | TypeTableEntry *value_type = analyze_expression(g, import, context, |
| 2125 | type_enum_field->type_entry, value_node); |
| 2126 | |
| 2127 | if (value_type->id == TypeTableEntryIdInvalid) { |
| 2128 | return g->builtin_types.entry_invalid; |
| 2129 | } |
| 2123 | 2130 | |
| 2124 | 2131 | StructValExprCodeGen *codegen = &field_access_node->data.field_access_expr.resolved_struct_val_expr; |
| 2125 | 2132 | codegen->type_entry = enum_type; |
| 2126 | 2133 | codegen->source_node = field_access_node; |
| 2127 | | context->fn_entry->struct_val_expr_alloca_list.append(codegen); |
| 2128 | 2134 | |
| 2129 | | Expr *expr = get_resolved_expr(field_access_node); |
| 2130 | | expr->const_val.ok = false; |
| 2135 | ConstExprValue *value_const_val = &get_resolved_expr(*value_node_ptr)->const_val; |
| 2136 | if (value_const_val->ok) { |
| 2137 | ConstExprValue *const_val = &get_resolved_expr(out_node)->const_val; |
| 2138 | const_val->ok = true; |
| 2139 | const_val->data.x_enum.tag = type_enum_field->value; |
| 2140 | const_val->data.x_enum.payload = value_const_val; |
| 2141 | } else { |
| 2142 | if (context->fn_entry) { |
| 2143 | context->fn_entry->struct_val_expr_alloca_list.append(codegen); |
| 2144 | } else { |
| 2145 | add_node_error(g, *value_node_ptr, buf_sprintf("unable to evaluate constant expression")); |
| 2146 | return g->builtin_types.entry_invalid; |
| 2147 | } |
| 2148 | } |
| 2131 | 2149 | } else if (type_enum_field->type_entry->id != TypeTableEntryIdVoid) { |
| 2132 | 2150 | add_node_error(g, field_access_node, |
| 2133 | 2151 | buf_sprintf("enum value '%s.%s' requires parameter of type '%s'", |
| ... | ... | @@ -2135,7 +2153,7 @@ static TypeTableEntry *analyze_enum_value_expr(CodeGen *g, ImportTableEntry *imp |
| 2135 | 2153 | buf_ptr(field_name), |
| 2136 | 2154 | buf_ptr(&type_enum_field->type_entry->name))); |
| 2137 | 2155 | } else { |
| 2138 | | Expr *expr = get_resolved_expr(field_access_node); |
| 2156 | Expr *expr = get_resolved_expr(out_node); |
| 2139 | 2157 | expr->const_val.ok = true; |
| 2140 | 2158 | expr->const_val.data.x_enum.tag = type_enum_field->value; |
| 2141 | 2159 | expr->const_val.data.x_enum.payload = nullptr; |
| ... | ... | @@ -2396,7 +2414,7 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i |
| 2396 | 2414 | } else if (wrapped_in_fn_call) { |
| 2397 | 2415 | return resolve_expr_const_val_as_type(g, node, child_type); |
| 2398 | 2416 | } else if (child_type->id == TypeTableEntryIdEnum) { |
| 2399 | | return analyze_enum_value_expr(g, import, context, node, nullptr, child_type, field_name); |
| 2417 | return analyze_enum_value_expr(g, import, context, node, nullptr, child_type, field_name, node); |
| 2400 | 2418 | } else if (child_type->id == TypeTableEntryIdStruct) { |
| 2401 | 2419 | BlockContext *container_block_context = get_container_block_context(child_type); |
| 2402 | 2420 | auto entry = container_block_context->decl_table.maybe_get(field_name); |
| ... | ... | @@ -4725,7 +4743,7 @@ static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import |
| 4725 | 4743 | node->data.fn_call_expr.enum_type = child_type; |
| 4726 | 4744 | |
| 4727 | 4745 | return analyze_enum_value_expr(g, import, context, fn_ref_expr, value_node, |
| 4728 | | child_type, field_name); |
| 4746 | child_type, field_name, node); |
| 4729 | 4747 | } |
| 4730 | 4748 | } else if (child_type->id == TypeTableEntryIdStruct) { |
| 4731 | 4749 | Buf *field_name = &fn_ref_expr->data.field_access_expr.field_name; |