| ... | @@ -756,11 +756,11 @@ static TypeTableEntryId container_to_type(ContainerKind kind) { | ... | @@ -756,11 +756,11 @@ static TypeTableEntryId container_to_type(ContainerKind kind) { |
| 756 | zig_unreachable(); | 756 | zig_unreachable(); |
| 757 | } | 757 | } |
| 758 | | 758 | |
| 759 | TypeTableEntry *get_partial_container_type(CodeGen *g, ImportTableEntry *import, | 759 | TypeTableEntry *get_partial_container_type(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| 760 | ContainerKind kind, AstNode *decl_node, const char *name) | 760 | ContainerKind kind, AstNode *decl_node, const char *name) |
| 761 | { | 761 | { |
| 762 | TypeTableEntryId type_id = container_to_type(kind); | 762 | TypeTableEntryId type_id = container_to_type(kind); |
| 763 | TypeTableEntry *entry = new_container_type_entry(type_id, decl_node, import->block_context); | 763 | TypeTableEntry *entry = new_container_type_entry(type_id, decl_node, context); |
| 764 | | 764 | |
| 765 | switch (kind) { | 765 | switch (kind) { |
| 766 | case ContainerKindStruct: | 766 | case ContainerKindStruct: |
| ... | @@ -1171,6 +1171,8 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt | ... | @@ -1171,6 +1171,8 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt |
| 1171 | uint64_t biggest_align_in_bits = 0; | 1171 | uint64_t biggest_align_in_bits = 0; |
| 1172 | uint64_t biggest_union_member_size_in_bits = 0; | 1172 | uint64_t biggest_union_member_size_in_bits = 0; |
| 1173 | | 1173 | |
| | 1174 | BlockContext *context = enum_type->data.enumeration.block_context; |
| | 1175 | |
| 1174 | // set temporary flag | 1176 | // set temporary flag |
| 1175 | enum_type->data.enumeration.embedded_in_current = true; | 1177 | enum_type->data.enumeration.embedded_in_current = true; |
| 1176 | | 1178 | |
| ... | @@ -1179,7 +1181,7 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt | ... | @@ -1179,7 +1181,7 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt |
| 1179 | AstNode *field_node = decl_node->data.struct_decl.fields.at(i); | 1181 | AstNode *field_node = decl_node->data.struct_decl.fields.at(i); |
| 1180 | TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i]; | 1182 | TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i]; |
| 1181 | type_enum_field->name = &field_node->data.struct_field.name; | 1183 | type_enum_field->name = &field_node->data.struct_field.name; |
| 1182 | TypeTableEntry *field_type = analyze_type_expr(g, import, import->block_context, | 1184 | TypeTableEntry *field_type = analyze_type_expr(g, import, context, |
| 1183 | field_node->data.struct_field.type); | 1185 | field_node->data.struct_field.type); |
| 1184 | type_enum_field->type_entry = field_type; | 1186 | type_enum_field->type_entry = field_type; |
| 1185 | type_enum_field->value = i; | 1187 | type_enum_field->value = i; |
| ... | @@ -1362,12 +1364,14 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE | ... | @@ -1362,12 +1364,14 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE |
| 1362 | // this field should be set to true only during the recursive calls to resolve_struct_type | 1364 | // this field should be set to true only during the recursive calls to resolve_struct_type |
| 1363 | struct_type->data.structure.embedded_in_current = true; | 1365 | struct_type->data.structure.embedded_in_current = true; |
| 1364 | | 1366 | |
| | 1367 | BlockContext *context = struct_type->data.structure.block_context; |
| | 1368 | |
| 1365 | int gen_field_index = 0; | 1369 | int gen_field_index = 0; |
| 1366 | for (int i = 0; i < field_count; i += 1) { | 1370 | for (int i = 0; i < field_count; i += 1) { |
| 1367 | AstNode *field_node = decl_node->data.struct_decl.fields.at(i); | 1371 | AstNode *field_node = decl_node->data.struct_decl.fields.at(i); |
| 1368 | TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; | 1372 | TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; |
| 1369 | type_struct_field->name = &field_node->data.struct_field.name; | 1373 | type_struct_field->name = &field_node->data.struct_field.name; |
| 1370 | TypeTableEntry *field_type = analyze_type_expr(g, import, import->block_context, | 1374 | TypeTableEntry *field_type = analyze_type_expr(g, import, context, |
| 1371 | field_node->data.struct_field.type); | 1375 | field_node->data.struct_field.type); |
| 1372 | type_struct_field->type_entry = field_type; | 1376 | type_struct_field->type_entry = field_type; |
| 1373 | type_struct_field->src_index = i; | 1377 | type_struct_field->src_index = i; |
| ... | @@ -1469,16 +1473,28 @@ static void get_fully_qualified_decl_name(Buf *buf, AstNode *decl_node, uint8_t | ... | @@ -1469,16 +1473,28 @@ static void get_fully_qualified_decl_name(Buf *buf, AstNode *decl_node, uint8_t |
| 1469 | } | 1473 | } |
| 1470 | | 1474 | |
| 1471 | static void preview_generic_fn_proto(CodeGen *g, ImportTableEntry *import, AstNode *node) { | 1475 | static void preview_generic_fn_proto(CodeGen *g, ImportTableEntry *import, AstNode *node) { |
| 1472 | assert(node->type == NodeTypeFnProto); | 1476 | if (node->type == NodeTypeFnProto) { |
| | 1477 | if (node->data.fn_proto.generic_params_is_var_args) { |
| | 1478 | add_node_error(g, node, buf_sprintf("generic parameters cannot be var args")); |
| | 1479 | node->data.fn_proto.skip = true; |
| | 1480 | node->data.fn_proto.generic_fn_type = g->builtin_types.entry_invalid; |
| | 1481 | return; |
| | 1482 | } |
| 1473 | | 1483 | |
| 1474 | if (node->data.fn_proto.generic_params_is_var_args) { | 1484 | node->data.fn_proto.generic_fn_type = get_generic_fn_type(g, node); |
| 1475 | add_node_error(g, node, buf_sprintf("generic parameters cannot be var args")); | 1485 | } else if (node->type == NodeTypeStructDecl) { |
| 1476 | node->data.fn_proto.skip = true; | 1486 | if (node->data.struct_decl.generic_params_is_var_args) { |
| 1477 | node->data.fn_proto.generic_fn_type = g->builtin_types.entry_invalid; | 1487 | add_node_error(g, node, buf_sprintf("generic parameters cannot be var args")); |
| 1478 | return; | 1488 | node->data.struct_decl.skip = true; |
| | 1489 | node->data.struct_decl.generic_fn_type = g->builtin_types.entry_invalid; |
| | 1490 | return; |
| | 1491 | } |
| | 1492 | |
| | 1493 | node->data.struct_decl.generic_fn_type = get_generic_fn_type(g, node); |
| | 1494 | } else { |
| | 1495 | zig_unreachable(); |
| 1479 | } | 1496 | } |
| 1480 | | 1497 | |
| 1481 | node->data.fn_proto.generic_fn_type = get_generic_fn_type(g, node); | | |
| 1482 | } | 1498 | } |
| 1483 | | 1499 | |
| 1484 | static void preview_fn_proto_instance(CodeGen *g, ImportTableEntry *import, AstNode *proto_node, | 1500 | static void preview_fn_proto_instance(CodeGen *g, ImportTableEntry *import, AstNode *proto_node, |
| ... | @@ -1538,6 +1554,50 @@ static void preview_fn_proto(CodeGen *g, ImportTableEntry *import, AstNode *prot | ... | @@ -1538,6 +1554,50 @@ static void preview_fn_proto(CodeGen *g, ImportTableEntry *import, AstNode *prot |
| 1538 | | 1554 | |
| 1539 | } | 1555 | } |
| 1540 | | 1556 | |
| | 1557 | static void scan_struct_decl(CodeGen *g, ImportTableEntry *import, BlockContext *context, AstNode *node) { |
| | 1558 | assert(node->type == NodeTypeStructDecl); |
| | 1559 | |
| | 1560 | Buf *name = &node->data.struct_decl.name; |
| | 1561 | TypeTableEntry *container_type = get_partial_container_type(g, import, context, |
| | 1562 | node->data.struct_decl.kind, node, buf_ptr(name)); |
| | 1563 | node->data.struct_decl.type_entry = container_type; |
| | 1564 | |
| | 1565 | // handle the member function definitions independently |
| | 1566 | for (int i = 0; i < node->data.struct_decl.fns.length; i += 1) { |
| | 1567 | AstNode *child_node = node->data.struct_decl.fns.at(i); |
| | 1568 | get_as_top_level_decl(child_node)->parent_decl = node; |
| | 1569 | BlockContext *child_context = get_container_block_context(container_type); |
| | 1570 | scan_decls(g, import, child_context, child_node); |
| | 1571 | } |
| | 1572 | } |
| | 1573 | |
| | 1574 | static void resolve_struct_instance(CodeGen *g, ImportTableEntry *import, AstNode *node) { |
| | 1575 | TypeTableEntry *type_entry = node->data.struct_decl.type_entry; |
| | 1576 | assert(type_entry); |
| | 1577 | |
| | 1578 | // struct/enum member fns will get resolved independently |
| | 1579 | |
| | 1580 | switch (node->data.struct_decl.kind) { |
| | 1581 | case ContainerKindStruct: |
| | 1582 | resolve_struct_type(g, import, type_entry); |
| | 1583 | break; |
| | 1584 | case ContainerKindEnum: |
| | 1585 | resolve_enum_type(g, import, type_entry); |
| | 1586 | break; |
| | 1587 | case ContainerKindUnion: |
| | 1588 | resolve_union_type(g, import, type_entry); |
| | 1589 | break; |
| | 1590 | } |
| | 1591 | } |
| | 1592 | |
| | 1593 | static void resolve_struct_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) { |
| | 1594 | if (node->data.struct_decl.generic_params.length > 0) { |
| | 1595 | return preview_generic_fn_proto(g, import, node); |
| | 1596 | } else { |
| | 1597 | return resolve_struct_instance(g, import, node); |
| | 1598 | } |
| | 1599 | } |
| | 1600 | |
| 1541 | static void preview_error_value_decl(CodeGen *g, AstNode *node) { | 1601 | static void preview_error_value_decl(CodeGen *g, AstNode *node) { |
| 1542 | assert(node->type == NodeTypeErrorValueDecl); | 1602 | assert(node->type == NodeTypeErrorValueDecl); |
| 1543 | | 1603 | |
| ... | @@ -1587,25 +1647,8 @@ static void resolve_top_level_decl(CodeGen *g, AstNode *node, bool pointer_only) | ... | @@ -1587,25 +1647,8 @@ static void resolve_top_level_decl(CodeGen *g, AstNode *node, bool pointer_only) |
| 1587 | preview_fn_proto(g, import, node); | 1647 | preview_fn_proto(g, import, node); |
| 1588 | break; | 1648 | break; |
| 1589 | case NodeTypeStructDecl: | 1649 | case NodeTypeStructDecl: |
| 1590 | { | 1650 | resolve_struct_decl(g, import, node); |
| 1591 | TypeTableEntry *type_entry = node->data.struct_decl.type_entry; | 1651 | break; |
| 1592 | | | |
| 1593 | // struct/enum member fns will get resolved independently | | |
| 1594 | | | |
| 1595 | switch (node->data.struct_decl.kind) { | | |
| 1596 | case ContainerKindStruct: | | |
| 1597 | resolve_struct_type(g, import, type_entry); | | |
| 1598 | break; | | |
| 1599 | case ContainerKindEnum: | | |
| 1600 | resolve_enum_type(g, import, type_entry); | | |
| 1601 | break; | | |
| 1602 | case ContainerKindUnion: | | |
| 1603 | resolve_union_type(g, import, type_entry); | | |
| 1604 | break; | | |
| 1605 | } | | |
| 1606 | | | |
| 1607 | break; | | |
| 1608 | } | | |
| 1609 | case NodeTypeVariableDeclaration: | 1652 | case NodeTypeVariableDeclaration: |
| 1610 | { | 1653 | { |
| 1611 | AstNodeVariableDeclaration *variable_declaration = &node->data.variable_declaration; | 1654 | AstNodeVariableDeclaration *variable_declaration = &node->data.variable_declaration; |
| ... | @@ -2729,6 +2772,7 @@ static TypeTableEntry *resolve_expr_const_val_as_generic_fn(CodeGen *g, AstNode | ... | @@ -2729,6 +2772,7 @@ static TypeTableEntry *resolve_expr_const_val_as_generic_fn(CodeGen *g, AstNode |
| 2729 | return type_entry; | 2772 | return type_entry; |
| 2730 | } | 2773 | } |
| 2731 | | 2774 | |
| | 2775 | |
| 2732 | static TypeTableEntry *resolve_expr_const_val_as_err(CodeGen *g, AstNode *node, ErrorTableEntry *err) { | 2776 | static TypeTableEntry *resolve_expr_const_val_as_err(CodeGen *g, AstNode *node, ErrorTableEntry *err) { |
| 2733 | Expr *expr = get_resolved_expr(node); | 2777 | Expr *expr = get_resolved_expr(node); |
| 2734 | expr->const_val.ok = true; | 2778 | expr->const_val.ok = true; |
| ... | @@ -2888,7 +2932,13 @@ static TypeTableEntry *analyze_decl_ref(CodeGen *g, AstNode *source_node, AstNod | ... | @@ -2888,7 +2932,13 @@ static TypeTableEntry *analyze_decl_ref(CodeGen *g, AstNode *source_node, AstNod |
| 2888 | return resolve_expr_const_val_as_fn(g, source_node, fn_entry); | 2932 | return resolve_expr_const_val_as_fn(g, source_node, fn_entry); |
| 2889 | } | 2933 | } |
| 2890 | } else if (decl_node->type == NodeTypeStructDecl) { | 2934 | } else if (decl_node->type == NodeTypeStructDecl) { |
| 2891 | return resolve_expr_const_val_as_type(g, source_node, decl_node->data.struct_decl.type_entry); | 2935 | if (decl_node->data.struct_decl.generic_params.length > 0) { |
| | 2936 | TypeTableEntry *type_entry = decl_node->data.struct_decl.generic_fn_type; |
| | 2937 | assert(type_entry); |
| | 2938 | return resolve_expr_const_val_as_generic_fn(g, source_node, type_entry); |
| | 2939 | } else { |
| | 2940 | return resolve_expr_const_val_as_type(g, source_node, decl_node->data.struct_decl.type_entry); |
| | 2941 | } |
| 2892 | } else if (decl_node->type == NodeTypeTypeDecl) { | 2942 | } else if (decl_node->type == NodeTypeTypeDecl) { |
| 2893 | return resolve_expr_const_val_as_type(g, source_node, decl_node->data.type_decl.child_type_entry); | 2943 | return resolve_expr_const_val_as_type(g, source_node, decl_node->data.type_decl.child_type_entry); |
| 2894 | } else { | 2944 | } else { |
| ... | @@ -5043,9 +5093,16 @@ static TypeTableEntry *analyze_generic_fn_call(CodeGen *g, ImportTableEntry *imp | ... | @@ -5043,9 +5093,16 @@ static TypeTableEntry *analyze_generic_fn_call(CodeGen *g, ImportTableEntry *imp |
| 5043 | assert(generic_fn_type->id == TypeTableEntryIdGenericFn); | 5093 | assert(generic_fn_type->id == TypeTableEntryIdGenericFn); |
| 5044 | | 5094 | |
| 5045 | AstNode *decl_node = generic_fn_type->data.generic_fn.decl_node; | 5095 | AstNode *decl_node = generic_fn_type->data.generic_fn.decl_node; |
| 5046 | assert(decl_node->type == NodeTypeFnProto); | 5096 | ZigList<AstNode *> *generic_params; |
| | 5097 | if (decl_node->type == NodeTypeFnProto) { |
| | 5098 | generic_params = &decl_node->data.fn_proto.generic_params; |
| | 5099 | } else if (decl_node->type == NodeTypeStructDecl) { |
| | 5100 | generic_params = &decl_node->data.struct_decl.generic_params; |
| | 5101 | } else { |
| | 5102 | zig_unreachable(); |
| | 5103 | } |
| 5047 | | 5104 | |
| 5048 | int expected_param_count = decl_node->data.fn_proto.generic_params.length; | 5105 | int expected_param_count = generic_params->length; |
| 5049 | int actual_param_count = node->data.fn_call_expr.params.length; | 5106 | int actual_param_count = node->data.fn_call_expr.params.length; |
| 5050 | | 5107 | |
| 5051 | if (actual_param_count != expected_param_count) { | 5108 | if (actual_param_count != expected_param_count) { |
| ... | @@ -5061,7 +5118,7 @@ static TypeTableEntry *analyze_generic_fn_call(CodeGen *g, ImportTableEntry *imp | ... | @@ -5061,7 +5118,7 @@ static TypeTableEntry *analyze_generic_fn_call(CodeGen *g, ImportTableEntry *imp |
| 5061 | | 5118 | |
| 5062 | BlockContext *child_context = decl_node->owner->block_context; | 5119 | BlockContext *child_context = decl_node->owner->block_context; |
| 5063 | for (int i = 0; i < actual_param_count; i += 1) { | 5120 | for (int i = 0; i < actual_param_count; i += 1) { |
| 5064 | AstNode *generic_param_decl_node = decl_node->data.fn_proto.generic_params.at(i); | 5121 | AstNode *generic_param_decl_node = generic_params->at(i); |
| 5065 | assert(generic_param_decl_node->type == NodeTypeParamDecl); | 5122 | assert(generic_param_decl_node->type == NodeTypeParamDecl); |
| 5066 | | 5123 | |
| 5067 | AstNode **generic_param_type_node = &generic_param_decl_node->data.param_decl.type; | 5124 | AstNode **generic_param_type_node = &generic_param_decl_node->data.param_decl.type; |
| ... | @@ -5104,24 +5161,36 @@ static TypeTableEntry *analyze_generic_fn_call(CodeGen *g, ImportTableEntry *imp | ... | @@ -5104,24 +5161,36 @@ static TypeTableEntry *analyze_generic_fn_call(CodeGen *g, ImportTableEntry *imp |
| 5104 | auto entry = g->generic_table.maybe_get(generic_fn_type_id); | 5161 | auto entry = g->generic_table.maybe_get(generic_fn_type_id); |
| 5105 | if (entry) { | 5162 | if (entry) { |
| 5106 | AstNode *impl_decl_node = entry->value; | 5163 | AstNode *impl_decl_node = entry->value; |
| 5107 | assert(impl_decl_node->type == NodeTypeFnProto); | 5164 | if (impl_decl_node->type == NodeTypeFnProto) { |
| 5108 | FnTableEntry *fn_table_entry = impl_decl_node->data.fn_proto.fn_table_entry; | 5165 | FnTableEntry *fn_table_entry = impl_decl_node->data.fn_proto.fn_table_entry; |
| 5109 | return resolve_expr_const_val_as_fn(g, node, fn_table_entry); | 5166 | return resolve_expr_const_val_as_fn(g, node, fn_table_entry); |
| | 5167 | } else if (impl_decl_node->type == NodeTypeStructDecl) { |
| | 5168 | TypeTableEntry *type_entry = impl_decl_node->data.struct_decl.type_entry; |
| | 5169 | return resolve_expr_const_val_as_type(g, node, type_entry); |
| | 5170 | } else { |
| | 5171 | zig_unreachable(); |
| | 5172 | } |
| 5110 | } | 5173 | } |
| 5111 | | 5174 | |
| 5112 | // make a type from the generic parameters supplied | 5175 | // make a type from the generic parameters supplied |
| 5113 | assert(decl_node->type == NodeTypeFnProto); | 5176 | if (decl_node->type == NodeTypeFnProto) { |
| 5114 | AstNode *impl_fn_def_node = ast_clone_subtree(decl_node->data.fn_proto.fn_def_node, &g->next_node_index); | 5177 | AstNode *impl_fn_def_node = ast_clone_subtree(decl_node->data.fn_proto.fn_def_node, &g->next_node_index); |
| 5115 | AstNode *impl_decl_node = impl_fn_def_node->data.fn_def.fn_proto; | 5178 | AstNode *impl_decl_node = impl_fn_def_node->data.fn_def.fn_proto; |
| 5116 | | | |
| 5117 | | | |
| 5118 | | 5179 | |
| 5119 | preview_fn_proto_instance(g, import, impl_decl_node, child_context); | 5180 | preview_fn_proto_instance(g, import, impl_decl_node, child_context); |
| 5120 | | 5181 | g->generic_table.put(generic_fn_type_id, impl_decl_node); |
| 5121 | g->generic_table.put(generic_fn_type_id, impl_decl_node); | 5182 | FnTableEntry *fn_table_entry = impl_decl_node->data.fn_proto.fn_table_entry; |
| 5122 | | 5183 | return resolve_expr_const_val_as_fn(g, node, fn_table_entry); |
| 5123 | FnTableEntry *fn_table_entry = impl_decl_node->data.fn_proto.fn_table_entry; | 5184 | } else if (decl_node->type == NodeTypeStructDecl) { |
| 5124 | return resolve_expr_const_val_as_fn(g, node, fn_table_entry); | 5185 | AstNode *impl_decl_node = ast_clone_subtree(decl_node, &g->next_node_index); |
| | 5186 | g->generic_table.put(generic_fn_type_id, impl_decl_node); |
| | 5187 | scan_struct_decl(g, import, child_context, impl_decl_node); |
| | 5188 | TypeTableEntry *type_entry = impl_decl_node->data.struct_decl.type_entry; |
| | 5189 | resolve_struct_type(g, import, type_entry); |
| | 5190 | return resolve_expr_const_val_as_type(g, node, type_entry); |
| | 5191 | } else { |
| | 5192 | zig_unreachable(); |
| | 5193 | } |
| 5125 | } | 5194 | } |
| 5126 | | 5195 | |
| 5127 | static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, | 5196 | static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| ... | @@ -6065,7 +6134,8 @@ static void add_top_level_decl(CodeGen *g, ImportTableEntry *import, BlockContex | ... | @@ -6065,7 +6134,8 @@ static void add_top_level_decl(CodeGen *g, ImportTableEntry *import, BlockContex |
| 6065 | tld->name = name; | 6134 | tld->name = name; |
| 6066 | | 6135 | |
| 6067 | bool want_as_export = (g->check_unused || g->is_test_build || tld->visib_mod == VisibModExport); | 6136 | bool want_as_export = (g->check_unused || g->is_test_build || tld->visib_mod == VisibModExport); |
| 6068 | bool is_generic = (node->type == NodeTypeFnProto && node->data.fn_proto.generic_params.length > 0); | 6137 | bool is_generic = (node->type == NodeTypeFnProto && node->data.fn_proto.generic_params.length > 0) || |
| | 6138 | (node->type == NodeTypeStructDecl && node->data.struct_decl.generic_params.length > 0); |
| 6069 | if (!is_generic && want_as_export) { | 6139 | if (!is_generic && want_as_export) { |
| 6070 | g->export_queue.append(node); | 6140 | g->export_queue.append(node); |
| 6071 | } | 6141 | } |
| ... | @@ -6093,21 +6163,12 @@ static void scan_decls(CodeGen *g, ImportTableEntry *import, BlockContext *conte | ... | @@ -6093,21 +6163,12 @@ static void scan_decls(CodeGen *g, ImportTableEntry *import, BlockContext *conte |
| 6093 | case NodeTypeStructDecl: | 6163 | case NodeTypeStructDecl: |
| 6094 | { | 6164 | { |
| 6095 | Buf *name = &node->data.struct_decl.name; | 6165 | Buf *name = &node->data.struct_decl.name; |
| 6096 | TypeTableEntry *container_type = get_partial_container_type(g, import, | | |
| 6097 | node->data.struct_decl.kind, node, buf_ptr(name)); | | |
| 6098 | node->data.struct_decl.type_entry = container_type; | | |
| 6099 | add_top_level_decl(g, import, context, node, name); | 6166 | add_top_level_decl(g, import, context, node, name); |
| 6100 | | 6167 | if (node->data.struct_decl.generic_params.length == 0) { |
| 6101 | // handle the member function definitions independently | 6168 | scan_struct_decl(g, import, context, node); |
| 6102 | for (int i = 0; i < node->data.struct_decl.fns.length; i += 1) { | | |
| 6103 | AstNode *child_node = node->data.struct_decl.fns.at(i); | | |
| 6104 | get_as_top_level_decl(child_node)->parent_decl = node; | | |
| 6105 | BlockContext *child_context = get_container_block_context(container_type); | | |
| 6106 | scan_decls(g, import, child_context, child_node); | | |
| 6107 | } | 6169 | } |
| 6108 | | | |
| 6109 | break; | | |
| 6110 | } | 6170 | } |
| | 6171 | break; |
| 6111 | case NodeTypeFnDef: | 6172 | case NodeTypeFnDef: |
| 6112 | node->data.fn_def.fn_proto->data.fn_proto.fn_def_node = node; | 6173 | node->data.fn_def.fn_proto->data.fn_proto.fn_def_node = node; |
| 6113 | scan_decls(g, import, context, node->data.fn_def.fn_proto); | 6174 | scan_decls(g, import, context, node->data.fn_def.fn_proto); |