| ... | @@ -2110,7 +2110,8 @@ static TypeEnumField *get_enum_field(TypeTableEntry *enum_type, Buf *name) { | ... | @@ -2110,7 +2110,8 @@ static TypeEnumField *get_enum_field(TypeTableEntry *enum_type, Buf *name) { |
| 2110 | } | 2110 | } |
| 2111 | | 2111 | |
| 2112 | static TypeTableEntry *analyze_enum_value_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, | 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 | assert(field_access_node->type == NodeTypeFieldAccessExpr); | 2116 | assert(field_access_node->type == NodeTypeFieldAccessExpr); |
| 2116 | | 2117 | |
| ... | @@ -2119,15 +2120,32 @@ static TypeTableEntry *analyze_enum_value_expr(CodeGen *g, ImportTableEntry *imp | ... | @@ -2119,15 +2120,32 @@ static TypeTableEntry *analyze_enum_value_expr(CodeGen *g, ImportTableEntry *imp |
| 2119 | | 2120 | |
| 2120 | if (type_enum_field) { | 2121 | if (type_enum_field) { |
| 2121 | if (value_node) { | 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 | StructValExprCodeGen *codegen = &field_access_node->data.field_access_expr.resolved_struct_val_expr; | 2131 | StructValExprCodeGen *codegen = &field_access_node->data.field_access_expr.resolved_struct_val_expr; |
| 2125 | codegen->type_entry = enum_type; | 2132 | codegen->type_entry = enum_type; |
| 2126 | codegen->source_node = field_access_node; | 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); | 2135 | ConstExprValue *value_const_val = &get_resolved_expr(*value_node_ptr)->const_val; |
| 2130 | expr->const_val.ok = false; | 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 | } else if (type_enum_field->type_entry->id != TypeTableEntryIdVoid) { | 2149 | } else if (type_enum_field->type_entry->id != TypeTableEntryIdVoid) { |
| 2132 | add_node_error(g, field_access_node, | 2150 | add_node_error(g, field_access_node, |
| 2133 | buf_sprintf("enum value '%s.%s' requires parameter of type '%s'", | 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,7 +2153,7 @@ static TypeTableEntry *analyze_enum_value_expr(CodeGen *g, ImportTableEntry *imp |
| 2135 | buf_ptr(field_name), | 2153 | buf_ptr(field_name), |
| 2136 | buf_ptr(&type_enum_field->type_entry->name))); | 2154 | buf_ptr(&type_enum_field->type_entry->name))); |
| 2137 | } else { | 2155 | } else { |
| 2138 | Expr *expr = get_resolved_expr(field_access_node); | 2156 | Expr *expr = get_resolved_expr(out_node); |
| 2139 | expr->const_val.ok = true; | 2157 | expr->const_val.ok = true; |
| 2140 | expr->const_val.data.x_enum.tag = type_enum_field->value; | 2158 | expr->const_val.data.x_enum.tag = type_enum_field->value; |
| 2141 | expr->const_val.data.x_enum.payload = nullptr; | 2159 | expr->const_val.data.x_enum.payload = nullptr; |
| ... | @@ -2396,7 +2414,7 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i | ... | @@ -2396,7 +2414,7 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i |
| 2396 | } else if (wrapped_in_fn_call) { | 2414 | } else if (wrapped_in_fn_call) { |
| 2397 | return resolve_expr_const_val_as_type(g, node, child_type); | 2415 | return resolve_expr_const_val_as_type(g, node, child_type); |
| 2398 | } else if (child_type->id == TypeTableEntryIdEnum) { | 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 | } else if (child_type->id == TypeTableEntryIdStruct) { | 2418 | } else if (child_type->id == TypeTableEntryIdStruct) { |
| 2401 | BlockContext *container_block_context = get_container_block_context(child_type); | 2419 | BlockContext *container_block_context = get_container_block_context(child_type); |
| 2402 | auto entry = container_block_context->decl_table.maybe_get(field_name); | 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,7 +4743,7 @@ static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import |
| 4725 | node->data.fn_call_expr.enum_type = child_type; | 4743 | node->data.fn_call_expr.enum_type = child_type; |
| 4726 | | 4744 | |
| 4727 | return analyze_enum_value_expr(g, import, context, fn_ref_expr, value_node, | 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 | } else if (child_type->id == TypeTableEntryIdStruct) { | 4748 | } else if (child_type->id == TypeTableEntryIdStruct) { |
| 4731 | Buf *field_name = &fn_ref_expr->data.field_access_expr.field_name; | 4749 | Buf *field_name = &fn_ref_expr->data.field_access_expr.field_name; |