| ... | @@ -57,6 +57,7 @@ static AstNode *first_executing_node(AstNode *node) { | ... | @@ -57,6 +57,7 @@ static AstNode *first_executing_node(AstNode *node) { |
| 57 | case NodeTypeBlock: | 57 | case NodeTypeBlock: |
| 58 | case NodeTypeDirective: | 58 | case NodeTypeDirective: |
| 59 | case NodeTypeReturnExpr: | 59 | case NodeTypeReturnExpr: |
| | 60 | case NodeTypeDeferExpr: |
| 60 | case NodeTypeVariableDeclaration: | 61 | case NodeTypeVariableDeclaration: |
| 61 | case NodeTypeTypeDecl: | 62 | case NodeTypeTypeDecl: |
| 62 | case NodeTypeErrorValueDecl: | 63 | case NodeTypeErrorValueDecl: |
| ... | @@ -865,23 +866,6 @@ static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_t | ... | @@ -865,23 +866,6 @@ static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_t |
| 865 | } | 866 | } |
| 866 | } | 867 | } |
| 867 | | 868 | |
| 868 | static void preview_function_labels(CodeGen *g, AstNode *node, FnTableEntry *fn_table_entry) { | | |
| 869 | assert(node->type == NodeTypeBlock); | | |
| 870 | | | |
| 871 | for (int i = 0; i < node->data.block.statements.length; i += 1) { | | |
| 872 | AstNode *label_node = node->data.block.statements.at(i); | | |
| 873 | if (label_node->type != NodeTypeLabel) | | |
| 874 | continue; | | |
| 875 | | | |
| 876 | LabelTableEntry *label_entry = allocate<LabelTableEntry>(1); | | |
| 877 | label_entry->label_node = label_node; | | |
| 878 | Buf *name = &label_node->data.label.name; | | |
| 879 | fn_table_entry->label_table.put(name, label_entry); | | |
| 880 | | | |
| 881 | label_node->data.label.label_entry = label_entry; | | |
| 882 | } | | |
| 883 | } | | |
| 884 | | | |
| 885 | static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *enum_type) { | 869 | static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *enum_type) { |
| 886 | // if you change this logic you likely must also change similar logic in parseh.cpp | 870 | // if you change this logic you likely must also change similar logic in parseh.cpp |
| 887 | assert(enum_type->id == TypeTableEntryIdEnum); | 871 | assert(enum_type->id == TypeTableEntryIdEnum); |
| ... | @@ -1233,7 +1217,6 @@ static void preview_fn_proto(CodeGen *g, ImportTableEntry *import, | ... | @@ -1233,7 +1217,6 @@ static void preview_fn_proto(CodeGen *g, ImportTableEntry *import, |
| 1233 | fn_table_entry->fn_def_node = fn_def_node; | 1217 | fn_table_entry->fn_def_node = fn_def_node; |
| 1234 | fn_table_entry->internal_linkage = !is_c_compat; | 1218 | fn_table_entry->internal_linkage = !is_c_compat; |
| 1235 | fn_table_entry->is_extern = is_extern; | 1219 | fn_table_entry->is_extern = is_extern; |
| 1236 | fn_table_entry->label_table.init(8); | | |
| 1237 | fn_table_entry->member_of_struct = struct_type; | 1220 | fn_table_entry->member_of_struct = struct_type; |
| 1238 | fn_table_entry->ref_count = (proto_node->data.fn_proto.visib_mod == VisibModExport) ? 1 : 0; | 1221 | fn_table_entry->ref_count = (proto_node->data.fn_proto.visib_mod == VisibModExport) ? 1 : 0; |
| 1239 | | 1222 | |
| ... | @@ -1272,10 +1255,6 @@ static void preview_fn_proto(CodeGen *g, ImportTableEntry *import, | ... | @@ -1272,10 +1255,6 @@ static void preview_fn_proto(CodeGen *g, ImportTableEntry *import, |
| 1272 | proto_node->data.fn_proto.fn_table_entry = fn_table_entry; | 1255 | proto_node->data.fn_proto.fn_table_entry = fn_table_entry; |
| 1273 | resolve_function_proto(g, proto_node, fn_table_entry, import); | 1256 | resolve_function_proto(g, proto_node, fn_table_entry, import); |
| 1274 | | 1257 | |
| 1275 | if (fn_def_node) { | | |
| 1276 | preview_function_labels(g, fn_def_node->data.fn_def.body, fn_table_entry); | | |
| 1277 | } | | |
| 1278 | | | |
| 1279 | if (is_pub && !struct_type) { | 1258 | if (is_pub && !struct_type) { |
| 1280 | for (int i = 0; i < import->importers.length; i += 1) { | 1259 | for (int i = 0; i < import->importers.length; i += 1) { |
| 1281 | ImporterInfo importer = import->importers.at(i); | 1260 | ImporterInfo importer = import->importers.at(i); |
| ... | @@ -1317,13 +1296,13 @@ static void resolve_error_value_decl(CodeGen *g, ImportTableEntry *import, AstNo | ... | @@ -1317,13 +1296,13 @@ static void resolve_error_value_decl(CodeGen *g, ImportTableEntry *import, AstNo |
| 1317 | | 1296 | |
| 1318 | ErrorTableEntry *err = node->data.error_value_decl.err; | 1297 | ErrorTableEntry *err = node->data.error_value_decl.err; |
| 1319 | | 1298 | |
| 1320 | import->block_context->error_table.put(&err->name, err); | 1299 | import->error_table.put(&err->name, err); |
| 1321 | | 1300 | |
| 1322 | bool is_pub = (node->data.error_value_decl.visib_mod != VisibModPrivate); | 1301 | bool is_pub = (node->data.error_value_decl.visib_mod != VisibModPrivate); |
| 1323 | if (is_pub) { | 1302 | if (is_pub) { |
| 1324 | for (int i = 0; i < import->importers.length; i += 1) { | 1303 | for (int i = 0; i < import->importers.length; i += 1) { |
| 1325 | ImporterInfo importer = import->importers.at(i); | 1304 | ImporterInfo importer = import->importers.at(i); |
| 1326 | importer.import->block_context->error_table.put(&err->name, err); | 1305 | importer.import->error_table.put(&err->name, err); |
| 1327 | } | 1306 | } |
| 1328 | } | 1307 | } |
| 1329 | } | 1308 | } |
| ... | @@ -1347,6 +1326,8 @@ static void resolve_c_import_decl(CodeGen *g, ImportTableEntry *parent_import, A | ... | @@ -1347,6 +1326,8 @@ static void resolve_c_import_decl(CodeGen *g, ImportTableEntry *parent_import, A |
| 1347 | | 1326 | |
| 1348 | ImportTableEntry *child_import = allocate<ImportTableEntry>(1); | 1327 | ImportTableEntry *child_import = allocate<ImportTableEntry>(1); |
| 1349 | child_import->fn_table.init(32); | 1328 | child_import->fn_table.init(32); |
| | 1329 | child_import->type_table.init(8); |
| | 1330 | child_import->error_table.init(8); |
| 1350 | child_import->c_import_node = node; | 1331 | child_import->c_import_node = node; |
| 1351 | | 1332 | |
| 1352 | ZigList<ErrorMsg *> errors = {0}; | 1333 | ZigList<ErrorMsg *> errors = {0}; |
| ... | @@ -1442,19 +1423,19 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode | ... | @@ -1442,19 +1423,19 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode |
| 1442 | } | 1423 | } |
| 1443 | } | 1424 | } |
| 1444 | | 1425 | |
| 1445 | import->block_context->type_table.put(decl_name, entry); | 1426 | import->type_table.put(decl_name, entry); |
| 1446 | | 1427 | |
| 1447 | bool is_pub = (node->data.type_decl.visib_mod != VisibModPrivate); | 1428 | bool is_pub = (node->data.type_decl.visib_mod != VisibModPrivate); |
| 1448 | if (is_pub) { | 1429 | if (is_pub) { |
| 1449 | for (int i = 0; i < import->importers.length; i += 1) { | 1430 | for (int i = 0; i < import->importers.length; i += 1) { |
| 1450 | ImporterInfo importer = import->importers.at(i); | 1431 | ImporterInfo importer = import->importers.at(i); |
| 1451 | auto table_entry = importer.import->block_context->type_table.maybe_get(&entry->name); | 1432 | auto table_entry = importer.import->type_table.maybe_get(&entry->name); |
| 1452 | if (table_entry) { | 1433 | if (table_entry) { |
| 1453 | add_node_error(g, importer.source_node, | 1434 | add_node_error(g, importer.source_node, |
| 1454 | buf_sprintf("import of type '%s' overrides existing definition", | 1435 | buf_sprintf("import of type '%s' overrides existing definition", |
| 1455 | buf_ptr(&entry->name))); | 1436 | buf_ptr(&entry->name))); |
| 1456 | } else { | 1437 | } else { |
| 1457 | importer.import->block_context->type_table.put(&entry->name, entry); | 1438 | importer.import->type_table.put(&entry->name, entry); |
| 1458 | } | 1439 | } |
| 1459 | } | 1440 | } |
| 1460 | } | 1441 | } |
| ... | @@ -1475,6 +1456,7 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode | ... | @@ -1475,6 +1456,7 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode |
| 1475 | case NodeTypeParamDecl: | 1456 | case NodeTypeParamDecl: |
| 1476 | case NodeTypeFnDecl: | 1457 | case NodeTypeFnDecl: |
| 1477 | case NodeTypeReturnExpr: | 1458 | case NodeTypeReturnExpr: |
| | 1459 | case NodeTypeDeferExpr: |
| 1478 | case NodeTypeRoot: | 1460 | case NodeTypeRoot: |
| 1479 | case NodeTypeBlock: | 1461 | case NodeTypeBlock: |
| 1480 | case NodeTypeBinOpExpr: | 1462 | case NodeTypeBinOpExpr: |
| ... | @@ -1953,9 +1935,7 @@ BlockContext *new_block_context(AstNode *node, BlockContext *parent) { | ... | @@ -1953,9 +1935,7 @@ BlockContext *new_block_context(AstNode *node, BlockContext *parent) { |
| 1953 | BlockContext *context = allocate<BlockContext>(1); | 1935 | BlockContext *context = allocate<BlockContext>(1); |
| 1954 | context->node = node; | 1936 | context->node = node; |
| 1955 | context->parent = parent; | 1937 | context->parent = parent; |
| 1956 | context->variable_table.init(8); | 1938 | context->variable_table.init(4); |
| 1957 | context->type_table.init(8); | | |
| 1958 | context->error_table.init(8); | | |
| 1959 | | 1939 | |
| 1960 | if (parent) { | 1940 | if (parent) { |
| 1961 | context->parent_loop_node = parent->parent_loop_node; | 1941 | context->parent_loop_node = parent->parent_loop_node; |
| ... | @@ -1976,10 +1956,10 @@ BlockContext *new_block_context(AstNode *node, BlockContext *parent) { | ... | @@ -1976,10 +1956,10 @@ BlockContext *new_block_context(AstNode *node, BlockContext *parent) { |
| 1976 | return context; | 1956 | return context; |
| 1977 | } | 1957 | } |
| 1978 | | 1958 | |
| 1979 | static VariableTableEntry *find_local_variable(BlockContext *context, Buf *name) { | 1959 | static VariableTableEntry *find_variable(BlockContext *context, Buf *name, bool local_only) { |
| 1980 | while (context && context->fn_entry) { | 1960 | while (context && (!local_only || context->fn_entry)) { |
| 1981 | auto entry = context->variable_table.maybe_get(name); | 1961 | auto entry = context->variable_table.maybe_get(name); |
| 1982 | if (entry != nullptr) | 1962 | if (entry) |
| 1983 | return entry->value; | 1963 | return entry->value; |
| 1984 | | 1964 | |
| 1985 | context = context->parent; | 1965 | context = context->parent; |
| ... | @@ -1987,26 +1967,12 @@ static VariableTableEntry *find_local_variable(BlockContext *context, Buf *name) | ... | @@ -1987,26 +1967,12 @@ static VariableTableEntry *find_local_variable(BlockContext *context, Buf *name) |
| 1987 | return nullptr; | 1967 | return nullptr; |
| 1988 | } | 1968 | } |
| 1989 | | 1969 | |
| 1990 | VariableTableEntry *find_variable(BlockContext *context, Buf *name) { | 1970 | static TypeTableEntry *find_container(ImportTableEntry *import, Buf *name) { |
| 1991 | while (context) { | 1971 | auto entry = import->type_table.maybe_get(name); |
| 1992 | auto entry = context->variable_table.maybe_get(name); | 1972 | if (entry) |
| 1993 | if (entry != nullptr) | 1973 | return entry->value; |
| 1994 | return entry->value; | 1974 | else |
| 1995 | | 1975 | return nullptr; |
| 1996 | context = context->parent; | | |
| 1997 | } | | |
| 1998 | return nullptr; | | |
| 1999 | } | | |
| 2000 | | | |
| 2001 | TypeTableEntry *find_container(BlockContext *context, Buf *name) { | | |
| 2002 | while (context) { | | |
| 2003 | auto entry = context->type_table.maybe_get(name); | | |
| 2004 | if (entry != nullptr) | | |
| 2005 | return entry->value; | | |
| 2006 | | | |
| 2007 | context = context->parent; | | |
| 2008 | } | | |
| 2009 | return nullptr; | | |
| 2010 | } | 1976 | } |
| 2011 | | 1977 | |
| 2012 | static TypeEnumField *get_enum_field(TypeTableEntry *enum_type, Buf *name) { | 1978 | static TypeEnumField *get_enum_field(TypeTableEntry *enum_type, Buf *name) { |
| ... | @@ -2034,7 +2000,7 @@ static TypeTableEntry *analyze_enum_value_expr(CodeGen *g, ImportTableEntry *imp | ... | @@ -2034,7 +2000,7 @@ static TypeTableEntry *analyze_enum_value_expr(CodeGen *g, ImportTableEntry *imp |
| 2034 | StructValExprCodeGen *codegen = &field_access_node->data.field_access_expr.resolved_struct_val_expr; | 2000 | StructValExprCodeGen *codegen = &field_access_node->data.field_access_expr.resolved_struct_val_expr; |
| 2035 | codegen->type_entry = enum_type; | 2001 | codegen->type_entry = enum_type; |
| 2036 | codegen->source_node = field_access_node; | 2002 | codegen->source_node = field_access_node; |
| 2037 | context->struct_val_expr_alloca_list.append(codegen); | 2003 | context->fn_entry->struct_val_expr_alloca_list.append(codegen); |
| 2038 | | 2004 | |
| 2039 | Expr *expr = get_resolved_expr(field_access_node); | 2005 | Expr *expr = get_resolved_expr(field_access_node); |
| 2040 | expr->const_val.ok = false; | 2006 | expr->const_val.ok = false; |
| ... | @@ -2099,7 +2065,6 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry | ... | @@ -2099,7 +2065,6 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry |
| 2099 | StructValExprCodeGen *codegen = &container_init_expr->resolved_struct_val_expr; | 2065 | StructValExprCodeGen *codegen = &container_init_expr->resolved_struct_val_expr; |
| 2100 | codegen->type_entry = container_type; | 2066 | codegen->type_entry = container_type; |
| 2101 | codegen->source_node = node; | 2067 | codegen->source_node = node; |
| 2102 | context->struct_val_expr_alloca_list.append(codegen); | | |
| 2103 | | 2068 | |
| 2104 | | 2069 | |
| 2105 | int expr_field_count = container_init_expr->entries.length; | 2070 | int expr_field_count = container_init_expr->entries.length; |
| ... | @@ -2150,6 +2115,9 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry | ... | @@ -2150,6 +2115,9 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry |
| 2150 | const_val->ok = false; | 2115 | const_val->ok = false; |
| 2151 | } | 2116 | } |
| 2152 | } | 2117 | } |
| | 2118 | if (!const_val->ok) { |
| | 2119 | context->fn_entry->struct_val_expr_alloca_list.append(codegen); |
| | 2120 | } |
| 2153 | } | 2121 | } |
| 2154 | | 2122 | |
| 2155 | for (int i = 0; i < actual_field_count; i += 1) { | 2123 | for (int i = 0; i < actual_field_count; i += 1) { |
| ... | @@ -2192,7 +2160,9 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry | ... | @@ -2192,7 +2160,9 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry |
| 2192 | StructValExprCodeGen *codegen = &container_init_expr->resolved_struct_val_expr; | 2160 | StructValExprCodeGen *codegen = &container_init_expr->resolved_struct_val_expr; |
| 2193 | codegen->type_entry = fixed_size_array_type; | 2161 | codegen->type_entry = fixed_size_array_type; |
| 2194 | codegen->source_node = node; | 2162 | codegen->source_node = node; |
| 2195 | context->struct_val_expr_alloca_list.append(codegen); | 2163 | if (!const_val->ok) { |
| | 2164 | context->fn_entry->struct_val_expr_alloca_list.append(codegen); |
| | 2165 | } |
| 2196 | | 2166 | |
| 2197 | return fixed_size_array_type; | 2167 | return fixed_size_array_type; |
| 2198 | } else if (container_type->id == TypeTableEntryIdArray) { | 2168 | } else if (container_type->id == TypeTableEntryIdArray) { |
| ... | @@ -2339,7 +2309,7 @@ static TypeTableEntry *analyze_slice_expr(CodeGen *g, ImportTableEntry *import, | ... | @@ -2339,7 +2309,7 @@ static TypeTableEntry *analyze_slice_expr(CodeGen *g, ImportTableEntry *import, |
| 2339 | if (return_type->id != TypeTableEntryIdInvalid) { | 2309 | if (return_type->id != TypeTableEntryIdInvalid) { |
| 2340 | node->data.slice_expr.resolved_struct_val_expr.type_entry = return_type; | 2310 | node->data.slice_expr.resolved_struct_val_expr.type_entry = return_type; |
| 2341 | node->data.slice_expr.resolved_struct_val_expr.source_node = node; | 2311 | node->data.slice_expr.resolved_struct_val_expr.source_node = node; |
| 2342 | context->struct_val_expr_alloca_list.append(&node->data.slice_expr.resolved_struct_val_expr); | 2312 | context->fn_entry->struct_val_expr_alloca_list.append(&node->data.slice_expr.resolved_struct_val_expr); |
| 2343 | } | 2313 | } |
| 2344 | | 2314 | |
| 2345 | analyze_expression(g, import, context, g->builtin_types.entry_isize, node->data.slice_expr.start); | 2315 | analyze_expression(g, import, context, g->builtin_types.entry_isize, node->data.slice_expr.start); |
| ... | @@ -2518,7 +2488,7 @@ static TypeTableEntry *resolve_expr_const_val_as_bignum_op(CodeGen *g, AstNode * | ... | @@ -2518,7 +2488,7 @@ static TypeTableEntry *resolve_expr_const_val_as_bignum_op(CodeGen *g, AstNode * |
| 2518 | static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *import, | 2488 | static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *import, |
| 2519 | BlockContext *context, AstNode *node, Buf *err_name) | 2489 | BlockContext *context, AstNode *node, Buf *err_name) |
| 2520 | { | 2490 | { |
| 2521 | auto err_table_entry = import->block_context->error_table.maybe_get(err_name); | 2491 | auto err_table_entry = import->error_table.maybe_get(err_name); |
| 2522 | | 2492 | |
| 2523 | if (err_table_entry) { | 2493 | if (err_table_entry) { |
| 2524 | return resolve_expr_const_val_as_err(g, node, err_table_entry->value); | 2494 | return resolve_expr_const_val_as_err(g, node, err_table_entry->value); |
| ... | @@ -2545,7 +2515,7 @@ static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import, | ... | @@ -2545,7 +2515,7 @@ static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import, |
| 2545 | return resolve_expr_const_val_as_type(g, node, primitive_table_entry->value); | 2515 | return resolve_expr_const_val_as_type(g, node, primitive_table_entry->value); |
| 2546 | } | 2516 | } |
| 2547 | | 2517 | |
| 2548 | VariableTableEntry *var = find_variable(context, variable_name); | 2518 | VariableTableEntry *var = find_variable(context, variable_name, false); |
| 2549 | if (var) { | 2519 | if (var) { |
| 2550 | node->data.symbol_expr.variable = var; | 2520 | node->data.symbol_expr.variable = var; |
| 2551 | if (var->is_const) { | 2521 | if (var->is_const) { |
| ... | @@ -2561,7 +2531,7 @@ static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import, | ... | @@ -2561,7 +2531,7 @@ static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import, |
| 2561 | return var->type; | 2531 | return var->type; |
| 2562 | } | 2532 | } |
| 2563 | | 2533 | |
| 2564 | TypeTableEntry *container_type = find_container(context, variable_name); | 2534 | TypeTableEntry *container_type = find_container(import, variable_name); |
| 2565 | if (container_type) { | 2535 | if (container_type) { |
| 2566 | return resolve_expr_const_val_as_type(g, node, container_type); | 2536 | return resolve_expr_const_val_as_type(g, node, container_type); |
| 2567 | } | 2537 | } |
| ... | @@ -2641,7 +2611,7 @@ static TypeTableEntry *analyze_lvalue(CodeGen *g, ImportTableEntry *import, Bloc | ... | @@ -2641,7 +2611,7 @@ static TypeTableEntry *analyze_lvalue(CodeGen *g, ImportTableEntry *import, Bloc |
| 2641 | if (purpose == LValPurposeAddressOf) { | 2611 | if (purpose == LValPurposeAddressOf) { |
| 2642 | expected_rhs_type = analyze_symbol_expr(g, import, block_context, nullptr, lhs_node); | 2612 | expected_rhs_type = analyze_symbol_expr(g, import, block_context, nullptr, lhs_node); |
| 2643 | } else { | 2613 | } else { |
| 2644 | VariableTableEntry *var = find_variable(block_context, name); | 2614 | VariableTableEntry *var = find_variable(block_context, name, false); |
| 2645 | if (var) { | 2615 | if (var) { |
| 2646 | if (var->is_const) { | 2616 | if (var->is_const) { |
| 2647 | add_node_error(g, lhs_node, buf_sprintf("cannot assign to constant")); | 2617 | add_node_error(g, lhs_node, buf_sprintf("cannot assign to constant")); |
| ... | @@ -3011,21 +2981,18 @@ static TypeTableEntry *analyze_bin_op_expr(CodeGen *g, ImportTableEntry *import, | ... | @@ -3011,21 +2981,18 @@ static TypeTableEntry *analyze_bin_op_expr(CodeGen *g, ImportTableEntry *import, |
| 3011 | } | 2981 | } |
| 3012 | | 2982 | |
| 3013 | // Set name to nullptr to make the variable anonymous (not visible to programmer). | 2983 | // Set name to nullptr to make the variable anonymous (not visible to programmer). |
| 3014 | static VariableTableEntry *add_local_var(CodeGen *g, AstNode *source_node, BlockContext *context, | 2984 | static VariableTableEntry *add_local_var(CodeGen *g, AstNode *source_node, ImportTableEntry *import, |
| 3015 | Buf *name, TypeTableEntry *type_entry, bool is_const) | 2985 | BlockContext *context, Buf *name, TypeTableEntry *type_entry, bool is_const) |
| 3016 | { | 2986 | { |
| 3017 | VariableTableEntry *variable_entry = allocate<VariableTableEntry>(1); | 2987 | VariableTableEntry *variable_entry = allocate<VariableTableEntry>(1); |
| 3018 | variable_entry->type = type_entry; | 2988 | variable_entry->type = type_entry; |
| | 2989 | variable_entry->block_context = context; |
| 3019 | | 2990 | |
| 3020 | if (name) { | 2991 | if (name) { |
| 3021 | buf_init_from_buf(&variable_entry->name, name); | 2992 | buf_init_from_buf(&variable_entry->name, name); |
| 3022 | VariableTableEntry *existing_var; | 2993 | VariableTableEntry *existing_var; |
| 3023 | | 2994 | |
| 3024 | if (context->fn_entry) { | 2995 | existing_var = find_variable(context, name, context->fn_entry != nullptr); |
| 3025 | existing_var = find_local_variable(context, name); | | |
| 3026 | } else { | | |
| 3027 | existing_var = find_variable(context, name); | | |
| 3028 | } | | |
| 3029 | | 2996 | |
| 3030 | if (existing_var) { | 2997 | if (existing_var) { |
| 3031 | add_node_error(g, source_node, buf_sprintf("redeclaration of variable '%s'", buf_ptr(name))); | 2998 | add_node_error(g, source_node, buf_sprintf("redeclaration of variable '%s'", buf_ptr(name))); |
| ... | @@ -3036,7 +3003,7 @@ static VariableTableEntry *add_local_var(CodeGen *g, AstNode *source_node, Block | ... | @@ -3036,7 +3003,7 @@ static VariableTableEntry *add_local_var(CodeGen *g, AstNode *source_node, Block |
| 3036 | if (primitive_table_entry) { | 3003 | if (primitive_table_entry) { |
| 3037 | type = primitive_table_entry->value; | 3004 | type = primitive_table_entry->value; |
| 3038 | } else { | 3005 | } else { |
| 3039 | type = find_container(context, name); | 3006 | type = find_container(import, name); |
| 3040 | } | 3007 | } |
| 3041 | if (type) { | 3008 | if (type) { |
| 3042 | add_node_error(g, source_node, buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name))); | 3009 | add_node_error(g, source_node, buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name))); |
| ... | @@ -3045,10 +3012,11 @@ static VariableTableEntry *add_local_var(CodeGen *g, AstNode *source_node, Block | ... | @@ -3045,10 +3012,11 @@ static VariableTableEntry *add_local_var(CodeGen *g, AstNode *source_node, Block |
| 3045 | } | 3012 | } |
| 3046 | | 3013 | |
| 3047 | context->variable_table.put(&variable_entry->name, variable_entry); | 3014 | context->variable_table.put(&variable_entry->name, variable_entry); |
| 3048 | context->variable_list.append(variable_entry); | | |
| 3049 | } else { | 3015 | } else { |
| 3050 | buf_init_from_str(&variable_entry->name, "_anon"); | 3016 | buf_init_from_str(&variable_entry->name, "_anon"); |
| 3051 | context->variable_list.append(variable_entry); | 3017 | } |
| | 3018 | if (context->fn_entry) { |
| | 3019 | context->fn_entry->variable_list.append(variable_entry); |
| 3052 | } | 3020 | } |
| 3053 | | 3021 | |
| 3054 | variable_entry->is_const = is_const; | 3022 | variable_entry->is_const = is_const; |
| ... | @@ -3075,7 +3043,7 @@ static TypeTableEntry *analyze_unwrap_error_expr(CodeGen *g, ImportTableEntry *i | ... | @@ -3075,7 +3043,7 @@ static TypeTableEntry *analyze_unwrap_error_expr(CodeGen *g, ImportTableEntry *i |
| 3075 | child_context = new_block_context(node, parent_context); | 3043 | child_context = new_block_context(node, parent_context); |
| 3076 | var_node->block_context = child_context; | 3044 | var_node->block_context = child_context; |
| 3077 | Buf *var_name = &var_node->data.symbol_expr.symbol; | 3045 | Buf *var_name = &var_node->data.symbol_expr.symbol; |
| 3078 | node->data.unwrap_err_expr.var = add_local_var(g, var_node, child_context, var_name, | 3046 | node->data.unwrap_err_expr.var = add_local_var(g, var_node, import, child_context, var_name, |
| 3079 | g->builtin_types.entry_pure_error, true); | 3047 | g->builtin_types.entry_pure_error, true); |
| 3080 | } else { | 3048 | } else { |
| 3081 | child_context = parent_context; | 3049 | child_context = parent_context; |
| ... | @@ -3153,7 +3121,7 @@ static VariableTableEntry *analyze_variable_declaration_raw(CodeGen *g, ImportTa | ... | @@ -3153,7 +3121,7 @@ static VariableTableEntry *analyze_variable_declaration_raw(CodeGen *g, ImportTa |
| 3153 | TypeTableEntry *type = explicit_type != nullptr ? explicit_type : implicit_type; | 3121 | TypeTableEntry *type = explicit_type != nullptr ? explicit_type : implicit_type; |
| 3154 | assert(type != nullptr); // should have been caught by the parser | 3122 | assert(type != nullptr); // should have been caught by the parser |
| 3155 | | 3123 | |
| 3156 | VariableTableEntry *var = add_local_var(g, source_node, context, | 3124 | VariableTableEntry *var = add_local_var(g, source_node, import, context, |
| 3157 | &variable_declaration->symbol, type, is_const); | 3125 | &variable_declaration->symbol, type, is_const); |
| 3158 | | 3126 | |
| 3159 | variable_declaration->variable = var; | 3127 | variable_declaration->variable = var; |
| ... | @@ -3199,7 +3167,7 @@ static TypeTableEntry *analyze_null_literal_expr(CodeGen *g, ImportTableEntry *i | ... | @@ -3199,7 +3167,7 @@ static TypeTableEntry *analyze_null_literal_expr(CodeGen *g, ImportTableEntry *i |
| 3199 | | 3167 | |
| 3200 | node->data.null_literal.resolved_struct_val_expr.type_entry = expected_type; | 3168 | node->data.null_literal.resolved_struct_val_expr.type_entry = expected_type; |
| 3201 | node->data.null_literal.resolved_struct_val_expr.source_node = node; | 3169 | node->data.null_literal.resolved_struct_val_expr.source_node = node; |
| 3202 | block_context->struct_val_expr_alloca_list.append(&node->data.null_literal.resolved_struct_val_expr); | 3170 | block_context->fn_entry->struct_val_expr_alloca_list.append(&node->data.null_literal.resolved_struct_val_expr); |
| 3203 | | 3171 | |
| 3204 | return resolve_expr_const_val_as_null(g, node, expected_type); | 3172 | return resolve_expr_const_val_as_null(g, node, expected_type); |
| 3205 | } | 3173 | } |
| ... | @@ -3303,7 +3271,6 @@ static TypeTableEntry *analyze_while_expr(CodeGen *g, ImportTableEntry *import, | ... | @@ -3303,7 +3271,6 @@ static TypeTableEntry *analyze_while_expr(CodeGen *g, ImportTableEntry *import, |
| 3303 | | 3271 | |
| 3304 | BlockContext *child_context = new_block_context(node, context); | 3272 | BlockContext *child_context = new_block_context(node, context); |
| 3305 | child_context->parent_loop_node = node; | 3273 | child_context->parent_loop_node = node; |
| 3306 | node->data.while_expr.block_context = child_context; | | |
| 3307 | | 3274 | |
| 3308 | analyze_expression(g, import, child_context, g->builtin_types.entry_void, while_body_node); | 3275 | analyze_expression(g, import, child_context, g->builtin_types.entry_void, while_body_node); |
| 3309 | | 3276 | |
| ... | @@ -3359,16 +3326,16 @@ static TypeTableEntry *analyze_for_expr(CodeGen *g, ImportTableEntry *import, Bl | ... | @@ -3359,16 +3326,16 @@ static TypeTableEntry *analyze_for_expr(CodeGen *g, ImportTableEntry *import, Bl |
| 3359 | AstNode *elem_var_node = node->data.for_expr.elem_node; | 3326 | AstNode *elem_var_node = node->data.for_expr.elem_node; |
| 3360 | elem_var_node->block_context = child_context; | 3327 | elem_var_node->block_context = child_context; |
| 3361 | Buf *elem_var_name = &elem_var_node->data.symbol_expr.symbol; | 3328 | Buf *elem_var_name = &elem_var_node->data.symbol_expr.symbol; |
| 3362 | node->data.for_expr.elem_var = add_local_var(g, elem_var_node, child_context, elem_var_name, child_type, true); | 3329 | node->data.for_expr.elem_var = add_local_var(g, elem_var_node, import, child_context, elem_var_name, child_type, true); |
| 3363 | | 3330 | |
| 3364 | AstNode *index_var_node = node->data.for_expr.index_node; | 3331 | AstNode *index_var_node = node->data.for_expr.index_node; |
| 3365 | if (index_var_node) { | 3332 | if (index_var_node) { |
| 3366 | Buf *index_var_name = &index_var_node->data.symbol_expr.symbol; | 3333 | Buf *index_var_name = &index_var_node->data.symbol_expr.symbol; |
| 3367 | index_var_node->block_context = child_context; | 3334 | index_var_node->block_context = child_context; |
| 3368 | node->data.for_expr.index_var = add_local_var(g, index_var_node, child_context, index_var_name, | 3335 | node->data.for_expr.index_var = add_local_var(g, index_var_node, import, child_context, index_var_name, |
| 3369 | g->builtin_types.entry_isize, true); | 3336 | g->builtin_types.entry_isize, true); |
| 3370 | } else { | 3337 | } else { |
| 3371 | node->data.for_expr.index_var = add_local_var(g, node, child_context, nullptr, | 3338 | node->data.for_expr.index_var = add_local_var(g, node, import, child_context, nullptr, |
| 3372 | g->builtin_types.entry_isize, true); | 3339 | g->builtin_types.entry_isize, true); |
| 3373 | } | 3340 | } |
| 3374 | | 3341 | |
| ... | @@ -3617,6 +3584,21 @@ static void eval_const_expr_implicit_cast(CodeGen *g, AstNode *node, AstNode *ex | ... | @@ -3617,6 +3584,21 @@ static void eval_const_expr_implicit_cast(CodeGen *g, AstNode *node, AstNode *ex |
| 3617 | } | 3584 | } |
| 3618 | } | 3585 | } |
| 3619 | | 3586 | |
| | 3587 | static TypeTableEntry *resolve_cast(CodeGen *g, BlockContext *context, AstNode *node, |
| | 3588 | AstNode *expr_node, TypeTableEntry *wanted_type, CastOp op, bool need_alloca) |
| | 3589 | { |
| | 3590 | node->data.fn_call_expr.cast_op = op; |
| | 3591 | eval_const_expr_implicit_cast(g, node, expr_node); |
| | 3592 | if (need_alloca) { |
| | 3593 | if (context->fn_entry) { |
| | 3594 | context->fn_entry->cast_alloca_list.append(node); |
| | 3595 | } else { |
| | 3596 | assert(get_resolved_expr(node)->const_val.ok); |
| | 3597 | } |
| | 3598 | } |
| | 3599 | return wanted_type; |
| | 3600 | } |
| | 3601 | |
| 3620 | static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, | 3602 | static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| 3621 | AstNode *node) | 3603 | AstNode *node) |
| 3622 | { | 3604 | { |
| ... | @@ -3642,27 +3624,21 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B | ... | @@ -3642,27 +3624,21 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B |
| 3642 | | 3624 | |
| 3643 | // explicit match or non-const to const | 3625 | // explicit match or non-const to const |
| 3644 | if (types_match_const_cast_only(wanted_type, actual_type)) { | 3626 | if (types_match_const_cast_only(wanted_type, actual_type)) { |
| 3645 | node->data.fn_call_expr.cast_op = CastOpNoop; | 3627 | return resolve_cast(g, context, node, expr_node, wanted_type, CastOpNoop, false); |
| 3646 | eval_const_expr_implicit_cast(g, node, expr_node); | | |
| 3647 | return wanted_type; | | |
| 3648 | } | 3628 | } |
| 3649 | | 3629 | |
| 3650 | // explicit cast from bool to int | 3630 | // explicit cast from bool to int |
| 3651 | if (wanted_type->id == TypeTableEntryIdInt && | 3631 | if (wanted_type->id == TypeTableEntryIdInt && |
| 3652 | actual_type->id == TypeTableEntryIdBool) | 3632 | actual_type->id == TypeTableEntryIdBool) |
| 3653 | { | 3633 | { |
| 3654 | node->data.fn_call_expr.cast_op = CastOpBoolToInt; | 3634 | return resolve_cast(g, context, node, expr_node, wanted_type, CastOpBoolToInt, false); |
| 3655 | eval_const_expr_implicit_cast(g, node, expr_node); | | |
| 3656 | return wanted_type; | | |
| 3657 | } | 3635 | } |
| 3658 | | 3636 | |
| 3659 | // explicit cast from pointer to isize or usize | 3637 | // explicit cast from pointer to isize or usize |
| 3660 | if ((wanted_type == g->builtin_types.entry_isize || wanted_type == g->builtin_types.entry_usize) && | 3638 | if ((wanted_type == g->builtin_types.entry_isize || wanted_type == g->builtin_types.entry_usize) && |
| 3661 | actual_type->id == TypeTableEntryIdPointer) | 3639 | actual_type->id == TypeTableEntryIdPointer) |
| 3662 | { | 3640 | { |
| 3663 | node->data.fn_call_expr.cast_op = CastOpPtrToInt; | 3641 | return resolve_cast(g, context, node, expr_node, wanted_type, CastOpPtrToInt, false); |
| 3664 | eval_const_expr_implicit_cast(g, node, expr_node); | | |
| 3665 | return wanted_type; | | |
| 3666 | } | 3642 | } |
| 3667 | | 3643 | |
| 3668 | | 3644 | |
| ... | @@ -3670,9 +3646,7 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B | ... | @@ -3670,9 +3646,7 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B |
| 3670 | if (wanted_type->id == TypeTableEntryIdPointer && | 3646 | if (wanted_type->id == TypeTableEntryIdPointer && |
| 3671 | (actual_type == g->builtin_types.entry_isize || actual_type == g->builtin_types.entry_usize)) | 3647 | (actual_type == g->builtin_types.entry_isize || actual_type == g->builtin_types.entry_usize)) |
| 3672 | { | 3648 | { |
| 3673 | node->data.fn_call_expr.cast_op = CastOpIntToPtr; | 3649 | return resolve_cast(g, context, node, expr_node, wanted_type, CastOpIntToPtr, false); |
| 3674 | eval_const_expr_implicit_cast(g, node, expr_node); | | |
| 3675 | return wanted_type; | | |
| 3676 | } | 3650 | } |
| 3677 | | 3651 | |
| 3678 | // explicit widening or shortening cast | 3652 | // explicit widening or shortening cast |
| ... | @@ -3681,27 +3655,21 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B | ... | @@ -3681,27 +3655,21 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B |
| 3681 | (wanted_type->id == TypeTableEntryIdFloat && | 3655 | (wanted_type->id == TypeTableEntryIdFloat && |
| 3682 | actual_type->id == TypeTableEntryIdFloat)) | 3656 | actual_type->id == TypeTableEntryIdFloat)) |
| 3683 | { | 3657 | { |
| 3684 | node->data.fn_call_expr.cast_op = CastOpWidenOrShorten; | 3658 | return resolve_cast(g, context, node, expr_node, wanted_type, CastOpWidenOrShorten, false); |
| 3685 | eval_const_expr_implicit_cast(g, node, expr_node); | | |
| 3686 | return wanted_type; | | |
| 3687 | } | 3659 | } |
| 3688 | | 3660 | |
| 3689 | // explicit cast from int to float | 3661 | // explicit cast from int to float |
| 3690 | if (wanted_type->id == TypeTableEntryIdFloat && | 3662 | if (wanted_type->id == TypeTableEntryIdFloat && |
| 3691 | actual_type->id == TypeTableEntryIdInt) | 3663 | actual_type->id == TypeTableEntryIdInt) |
| 3692 | { | 3664 | { |
| 3693 | node->data.fn_call_expr.cast_op = CastOpIntToFloat; | 3665 | return resolve_cast(g, context, node, expr_node, wanted_type, CastOpIntToFloat, false); |
| 3694 | eval_const_expr_implicit_cast(g, node, expr_node); | | |
| 3695 | return wanted_type; | | |
| 3696 | } | 3666 | } |
| 3697 | | 3667 | |
| 3698 | // explicit cast from float to int | 3668 | // explicit cast from float to int |
| 3699 | if (wanted_type->id == TypeTableEntryIdInt && | 3669 | if (wanted_type->id == TypeTableEntryIdInt && |
| 3700 | actual_type->id == TypeTableEntryIdFloat) | 3670 | actual_type->id == TypeTableEntryIdFloat) |
| 3701 | { | 3671 | { |
| 3702 | node->data.fn_call_expr.cast_op = CastOpFloatToInt; | 3672 | return resolve_cast(g, context, node, expr_node, wanted_type, CastOpFloatToInt, false); |
| 3703 | eval_const_expr_implicit_cast(g, node, expr_node); | | |
| 3704 | return wanted_type; | | |
| 3705 | } | 3673 | } |
| 3706 | | 3674 | |
| 3707 | // explicit cast from fixed size array to unknown size array | 3675 | // explicit cast from fixed size array to unknown size array |
| ... | @@ -3712,36 +3680,25 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B | ... | @@ -3712,36 +3680,25 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B |
| 3712 | wanted_type->data.structure.fields[0].type_entry->data.pointer.child_type, | 3680 | wanted_type->data.structure.fields[0].type_entry->data.pointer.child_type, |
| 3713 | actual_type->data.array.child_type)) | 3681 | actual_type->data.array.child_type)) |
| 3714 | { | 3682 | { |
| 3715 | node->data.fn_call_expr.cast_op = CastOpToUnknownSizeArray; | 3683 | return resolve_cast(g, context, node, expr_node, wanted_type, CastOpToUnknownSizeArray, true); |
| 3716 | context->cast_alloca_list.append(node); | | |
| 3717 | eval_const_expr_implicit_cast(g, node, expr_node); | | |
| 3718 | return wanted_type; | | |
| 3719 | } | 3684 | } |
| 3720 | | 3685 | |
| 3721 | // explicit cast from pointer to another pointer | 3686 | // explicit cast from pointer to another pointer |
| 3722 | if (actual_type->id == TypeTableEntryIdPointer && | 3687 | if (actual_type->id == TypeTableEntryIdPointer && |
| 3723 | wanted_type->id == TypeTableEntryIdPointer) | 3688 | wanted_type->id == TypeTableEntryIdPointer) |
| 3724 | { | 3689 | { |
| 3725 | node->data.fn_call_expr.cast_op = CastOpPointerReinterpret; | 3690 | return resolve_cast(g, context, node, expr_node, wanted_type, CastOpPointerReinterpret, false); |
| 3726 | eval_const_expr_implicit_cast(g, node, expr_node); | | |
| 3727 | return wanted_type; | | |
| 3728 | } | 3691 | } |
| 3729 | | 3692 | |
| 3730 | // explicit cast from child type of maybe type to maybe type | 3693 | // explicit cast from child type of maybe type to maybe type |
| 3731 | if (wanted_type->id == TypeTableEntryIdMaybe) { | 3694 | if (wanted_type->id == TypeTableEntryIdMaybe) { |
| 3732 | if (types_match_const_cast_only(wanted_type->data.maybe.child_type, actual_type)) { | 3695 | if (types_match_const_cast_only(wanted_type->data.maybe.child_type, actual_type)) { |
| 3733 | node->data.fn_call_expr.cast_op = CastOpMaybeWrap; | 3696 | return resolve_cast(g, context, node, expr_node, wanted_type, CastOpMaybeWrap, true); |
| 3734 | context->cast_alloca_list.append(node); | | |
| 3735 | eval_const_expr_implicit_cast(g, node, expr_node); | | |
| 3736 | return wanted_type; | | |
| 3737 | } else if (actual_type->id == TypeTableEntryIdNumLitInt || | 3697 | } else if (actual_type->id == TypeTableEntryIdNumLitInt || |
| 3738 | actual_type->id == TypeTableEntryIdNumLitFloat) | 3698 | actual_type->id == TypeTableEntryIdNumLitFloat) |
| 3739 | { | 3699 | { |
| 3740 | if (num_lit_fits_in_other_type(g, expr_node, wanted_type->data.maybe.child_type)) { | 3700 | if (num_lit_fits_in_other_type(g, expr_node, wanted_type->data.maybe.child_type)) { |
| 3741 | node->data.fn_call_expr.cast_op = CastOpMaybeWrap; | 3701 | return resolve_cast(g, context, node, expr_node, wanted_type, CastOpMaybeWrap, true); |
| 3742 | context->cast_alloca_list.append(node); | | |
| 3743 | eval_const_expr_implicit_cast(g, node, expr_node); | | |
| 3744 | return wanted_type; | | |
| 3745 | } else { | 3702 | } else { |
| 3746 | return g->builtin_types.entry_invalid; | 3703 | return g->builtin_types.entry_invalid; |
| 3747 | } | 3704 | } |
| ... | @@ -3751,18 +3708,12 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B | ... | @@ -3751,18 +3708,12 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B |
| 3751 | // explicit cast from child type of error type to error type | 3708 | // explicit cast from child type of error type to error type |
| 3752 | if (wanted_type->id == TypeTableEntryIdErrorUnion) { | 3709 | if (wanted_type->id == TypeTableEntryIdErrorUnion) { |
| 3753 | if (types_match_const_cast_only(wanted_type->data.error.child_type, actual_type)) { | 3710 | if (types_match_const_cast_only(wanted_type->data.error.child_type, actual_type)) { |
| 3754 | node->data.fn_call_expr.cast_op = CastOpErrorWrap; | 3711 | return resolve_cast(g, context, node, expr_node, wanted_type, CastOpErrorWrap, true); |
| 3755 | context->cast_alloca_list.append(node); | | |
| 3756 | eval_const_expr_implicit_cast(g, node, expr_node); | | |
| 3757 | return wanted_type; | | |
| 3758 | } else if (actual_type->id == TypeTableEntryIdNumLitInt || | 3712 | } else if (actual_type->id == TypeTableEntryIdNumLitInt || |
| 3759 | actual_type->id == TypeTableEntryIdNumLitFloat) | 3713 | actual_type->id == TypeTableEntryIdNumLitFloat) |
| 3760 | { | 3714 | { |
| 3761 | if (num_lit_fits_in_other_type(g, expr_node, wanted_type->data.error.child_type)) { | 3715 | if (num_lit_fits_in_other_type(g, expr_node, wanted_type->data.error.child_type)) { |
| 3762 | node->data.fn_call_expr.cast_op = CastOpErrorWrap; | 3716 | return resolve_cast(g, context, node, expr_node, wanted_type, CastOpErrorWrap, true); |
| 3763 | context->cast_alloca_list.append(node); | | |
| 3764 | eval_const_expr_implicit_cast(g, node, expr_node); | | |
| 3765 | return wanted_type; | | |
| 3766 | } else { | 3717 | } else { |
| 3767 | return g->builtin_types.entry_invalid; | 3718 | return g->builtin_types.entry_invalid; |
| 3768 | } | 3719 | } |
| ... | @@ -3773,9 +3724,7 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B | ... | @@ -3773,9 +3724,7 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B |
| 3773 | if (wanted_type->id == TypeTableEntryIdErrorUnion && | 3724 | if (wanted_type->id == TypeTableEntryIdErrorUnion && |
| 3774 | actual_type->id == TypeTableEntryIdPureError) | 3725 | actual_type->id == TypeTableEntryIdPureError) |
| 3775 | { | 3726 | { |
| 3776 | node->data.fn_call_expr.cast_op = CastOpPureErrorWrap; | 3727 | return resolve_cast(g, context, node, expr_node, wanted_type, CastOpPureErrorWrap, false); |
| 3777 | eval_const_expr_implicit_cast(g, node, expr_node); | | |
| 3778 | return wanted_type; | | |
| 3779 | } | 3728 | } |
| 3780 | | 3729 | |
| 3781 | // explicit cast from number literal to another type | 3730 | // explicit cast from number literal to another type |
| ... | @@ -3783,21 +3732,21 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B | ... | @@ -3783,21 +3732,21 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B |
| 3783 | actual_type->id == TypeTableEntryIdNumLitInt) | 3732 | actual_type->id == TypeTableEntryIdNumLitInt) |
| 3784 | { | 3733 | { |
| 3785 | if (num_lit_fits_in_other_type(g, expr_node, wanted_type)) { | 3734 | if (num_lit_fits_in_other_type(g, expr_node, wanted_type)) { |
| | 3735 | CastOp op; |
| 3786 | if ((actual_type->id == TypeTableEntryIdNumLitFloat && | 3736 | if ((actual_type->id == TypeTableEntryIdNumLitFloat && |
| 3787 | wanted_type->id == TypeTableEntryIdFloat) || | 3737 | wanted_type->id == TypeTableEntryIdFloat) || |
| 3788 | (actual_type->id == TypeTableEntryIdNumLitInt && | 3738 | (actual_type->id == TypeTableEntryIdNumLitInt && |
| 3789 | wanted_type->id == TypeTableEntryIdInt)) | 3739 | wanted_type->id == TypeTableEntryIdInt)) |
| 3790 | { | 3740 | { |
| 3791 | node->data.fn_call_expr.cast_op = CastOpNoop; | 3741 | op = CastOpNoop; |
| 3792 | } else if (wanted_type->id == TypeTableEntryIdInt) { | 3742 | } else if (wanted_type->id == TypeTableEntryIdInt) { |
| 3793 | node->data.fn_call_expr.cast_op = CastOpFloatToInt; | 3743 | op = CastOpFloatToInt; |
| 3794 | } else if (wanted_type->id == TypeTableEntryIdFloat) { | 3744 | } else if (wanted_type->id == TypeTableEntryIdFloat) { |
| 3795 | node->data.fn_call_expr.cast_op = CastOpIntToFloat; | 3745 | op = CastOpIntToFloat; |
| 3796 | } else { | 3746 | } else { |
| 3797 | zig_unreachable(); | 3747 | zig_unreachable(); |
| 3798 | } | 3748 | } |
| 3799 | eval_const_expr_implicit_cast(g, node, expr_node); | 3749 | return resolve_cast(g, context, node, expr_node, wanted_type, op, false); |
| 3800 | return wanted_type; | | |
| 3801 | } else { | 3750 | } else { |
| 3802 | return g->builtin_types.entry_invalid; | 3751 | return g->builtin_types.entry_invalid; |
| 3803 | } | 3752 | } |
| ... | @@ -3815,9 +3764,7 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B | ... | @@ -3815,9 +3764,7 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B |
| 3815 | if (bignum_fits_in_bits(&bn, wanted_type->data.integral.bit_count, | 3764 | if (bignum_fits_in_bits(&bn, wanted_type->data.integral.bit_count, |
| 3816 | wanted_type->data.integral.is_signed)) | 3765 | wanted_type->data.integral.is_signed)) |
| 3817 | { | 3766 | { |
| 3818 | node->data.fn_call_expr.cast_op = CastOpErrToInt; | 3767 | return resolve_cast(g, context, node, expr_node, wanted_type, CastOpErrToInt, false); |
| 3819 | eval_const_expr_implicit_cast(g, node, expr_node); | | |
| 3820 | return wanted_type; | | |
| 3821 | } else { | 3768 | } else { |
| 3822 | add_node_error(g, node, | 3769 | add_node_error(g, node, |
| 3823 | buf_sprintf("too many error values to fit in '%s'", buf_ptr(&wanted_type->name))); | 3770 | buf_sprintf("too many error values to fit in '%s'", buf_ptr(&wanted_type->name))); |
| ... | @@ -4176,7 +4123,7 @@ static TypeTableEntry *analyze_fn_call_ptr(CodeGen *g, ImportTableEntry *import, | ... | @@ -4176,7 +4123,7 @@ static TypeTableEntry *analyze_fn_call_ptr(CodeGen *g, ImportTableEntry *import, |
| 4176 | } | 4123 | } |
| 4177 | | 4124 | |
| 4178 | if (handle_is_ptr(return_type)) { | 4125 | if (handle_is_ptr(return_type)) { |
| 4179 | context->cast_alloca_list.append(node); | 4126 | context->fn_entry->cast_alloca_list.append(node); |
| 4180 | } | 4127 | } |
| 4181 | | 4128 | |
| 4182 | return return_type; | 4129 | return return_type; |
| ... | @@ -4572,8 +4519,8 @@ static TypeTableEntry *analyze_switch_expr(CodeGen *g, ImportTableEntry *import, | ... | @@ -4572,8 +4519,8 @@ static TypeTableEntry *analyze_switch_expr(CodeGen *g, ImportTableEntry *import, |
| 4572 | assert(var_node->type == NodeTypeSymbol); | 4519 | assert(var_node->type == NodeTypeSymbol); |
| 4573 | Buf *var_name = &var_node->data.symbol_expr.symbol; | 4520 | Buf *var_name = &var_node->data.symbol_expr.symbol; |
| 4574 | var_node->block_context = child_context; | 4521 | var_node->block_context = child_context; |
| 4575 | prong_node->data.switch_prong.var = add_local_var(g, var_node, child_context, var_name, | 4522 | prong_node->data.switch_prong.var = add_local_var(g, var_node, import, |
| 4576 | var_type, true); | 4523 | child_context, var_name, var_type, true); |
| 4577 | prong_node->data.switch_prong.var_is_target_expr = var_is_target_expr; | 4524 | prong_node->data.switch_prong.var_is_target_expr = var_is_target_expr; |
| 4578 | } | 4525 | } |
| 4579 | | 4526 | |
| ... | @@ -4598,6 +4545,9 @@ static TypeTableEntry *analyze_return_expr(CodeGen *g, ImportTableEntry *import, | ... | @@ -4598,6 +4545,9 @@ static TypeTableEntry *analyze_return_expr(CodeGen *g, ImportTableEntry *import, |
| 4598 | normalize_parent_ptrs(node); | 4545 | normalize_parent_ptrs(node); |
| 4599 | } | 4546 | } |
| 4600 | | 4547 | |
| | 4548 | // TODO follow the blocks to their parents, loop over all of them, set them all to true |
| | 4549 | context->block_exit_paths[BlockExitPathReturn] = true; |
| | 4550 | |
| 4601 | TypeTableEntry *expected_return_type = get_return_type(context); | 4551 | TypeTableEntry *expected_return_type = get_return_type(context); |
| 4602 | | 4552 | |
| 4603 | switch (node->data.return_expr.kind) { | 4553 | switch (node->data.return_expr.kind) { |
| ... | @@ -4632,6 +4582,71 @@ static TypeTableEntry *analyze_return_expr(CodeGen *g, ImportTableEntry *import, | ... | @@ -4632,6 +4582,71 @@ static TypeTableEntry *analyze_return_expr(CodeGen *g, ImportTableEntry *import, |
| 4632 | } | 4582 | } |
| 4633 | } | 4583 | } |
| 4634 | | 4584 | |
| | 4585 | static void validate_voided_expr(CodeGen *g, AstNode *source_node, TypeTableEntry *type_entry) { |
| | 4586 | if (type_entry->id == TypeTableEntryIdMetaType) { |
| | 4587 | add_node_error(g, first_executing_node(source_node), buf_sprintf("expected expression, found type")); |
| | 4588 | } else if (type_entry->id == TypeTableEntryIdErrorUnion) { |
| | 4589 | add_node_error(g, first_executing_node(source_node), buf_sprintf("statement ignores error value")); |
| | 4590 | } |
| | 4591 | } |
| | 4592 | |
| | 4593 | static TypeTableEntry *analyze_defer_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| | 4594 | TypeTableEntry *expected_type, AstNode *node) |
| | 4595 | { |
| | 4596 | if (!context->fn_entry) { |
| | 4597 | add_node_error(g, node, buf_sprintf("defer expression outside function definition")); |
| | 4598 | return g->builtin_types.entry_invalid; |
| | 4599 | } |
| | 4600 | |
| | 4601 | if (!node->data.defer_expr.expr) { |
| | 4602 | add_node_error(g, node, buf_sprintf("defer expects an expression")); |
| | 4603 | return g->builtin_types.entry_void; |
| | 4604 | } |
| | 4605 | |
| | 4606 | |
| | 4607 | switch (node->data.defer_expr.kind) { |
| | 4608 | case ReturnKindUnconditional: |
| | 4609 | { |
| | 4610 | TypeTableEntry *resolved_type = analyze_expression(g, import, context, nullptr, |
| | 4611 | node->data.defer_expr.expr); |
| | 4612 | validate_voided_expr(g, node->data.defer_expr.expr, resolved_type); |
| | 4613 | zig_panic("TODO"); |
| | 4614 | |
| | 4615 | //node->data.defer_expr.index_in_block = context->defer_list.length; |
| | 4616 | //context->defer_list.append(node); |
| | 4617 | return g->builtin_types.entry_void; |
| | 4618 | } |
| | 4619 | case ReturnKindError: |
| | 4620 | { |
| | 4621 | TypeTableEntry *resolved_type = analyze_expression(g, import, context, nullptr, |
| | 4622 | node->data.defer_expr.expr); |
| | 4623 | if (resolved_type->id == TypeTableEntryIdInvalid) { |
| | 4624 | // OK |
| | 4625 | } else if (resolved_type->id == TypeTableEntryIdErrorUnion) { |
| | 4626 | // OK |
| | 4627 | } else { |
| | 4628 | add_node_error(g, node->data.defer_expr.expr, |
| | 4629 | buf_sprintf("expected error type, got '%s'", buf_ptr(&resolved_type->name))); |
| | 4630 | } |
| | 4631 | return g->builtin_types.entry_void; |
| | 4632 | } |
| | 4633 | case ReturnKindMaybe: |
| | 4634 | { |
| | 4635 | TypeTableEntry *resolved_type = analyze_expression(g, import, context, nullptr, |
| | 4636 | node->data.defer_expr.expr); |
| | 4637 | if (resolved_type->id == TypeTableEntryIdInvalid) { |
| | 4638 | // OK |
| | 4639 | } else if (resolved_type->id == TypeTableEntryIdMaybe) { |
| | 4640 | // OK |
| | 4641 | } else { |
| | 4642 | add_node_error(g, node->data.defer_expr.expr, |
| | 4643 | buf_sprintf("expected maybe type, got '%s'", buf_ptr(&resolved_type->name))); |
| | 4644 | } |
| | 4645 | return g->builtin_types.entry_void; |
| | 4646 | } |
| | 4647 | } |
| | 4648 | } |
| | 4649 | |
| 4635 | static TypeTableEntry *analyze_string_literal_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, | 4650 | static TypeTableEntry *analyze_string_literal_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| 4636 | TypeTableEntry *expected_type, AstNode *node) | 4651 | TypeTableEntry *expected_type, AstNode *node) |
| 4637 | { | 4652 | { |
| ... | @@ -4652,10 +4667,8 @@ static TypeTableEntry *analyze_block_expr(CodeGen *g, ImportTableEntry *import, | ... | @@ -4652,10 +4667,8 @@ static TypeTableEntry *analyze_block_expr(CodeGen *g, ImportTableEntry *import, |
| 4652 | for (int i = 0; i < node->data.block.statements.length; i += 1) { | 4667 | for (int i = 0; i < node->data.block.statements.length; i += 1) { |
| 4653 | AstNode *child = node->data.block.statements.at(i); | 4668 | AstNode *child = node->data.block.statements.at(i); |
| 4654 | if (child->type == NodeTypeLabel) { | 4669 | if (child->type == NodeTypeLabel) { |
| 4655 | child->block_context = child_context; | 4670 | add_node_error(g, child, |
| 4656 | LabelTableEntry *label_entry = child->data.label.label_entry; | 4671 | buf_sprintf("label and goto not supported yet, see https://github.com/andrewrk/zig/issues/44")); |
| 4657 | assert(label_entry); | | |
| 4658 | label_entry->entered_from_fallthrough = (return_type->id != TypeTableEntryIdUnreachable); | | |
| 4659 | return_type = g->builtin_types.entry_void; | 4672 | return_type = g->builtin_types.entry_void; |
| 4660 | continue; | 4673 | continue; |
| 4661 | } | 4674 | } |
| ... | @@ -4673,11 +4686,7 @@ static TypeTableEntry *analyze_block_expr(CodeGen *g, ImportTableEntry *import, | ... | @@ -4673,11 +4686,7 @@ static TypeTableEntry *analyze_block_expr(CodeGen *g, ImportTableEntry *import, |
| 4673 | TypeTableEntry *passed_expected_type = is_last ? expected_type : nullptr; | 4686 | TypeTableEntry *passed_expected_type = is_last ? expected_type : nullptr; |
| 4674 | return_type = analyze_expression(g, import, child_context, passed_expected_type, child); | 4687 | return_type = analyze_expression(g, import, child_context, passed_expected_type, child); |
| 4675 | if (!is_last) { | 4688 | if (!is_last) { |
| 4676 | if (return_type->id == TypeTableEntryIdMetaType) { | 4689 | validate_voided_expr(g, child, return_type); |
| 4677 | add_node_error(g, child, buf_sprintf("expected expression, found type")); | | |
| 4678 | } else if (return_type->id == TypeTableEntryIdErrorUnion) { | | |
| 4679 | add_node_error(g, child, buf_sprintf("statement ignores error value")); | | |
| 4680 | } | | |
| 4681 | } | 4690 | } |
| 4682 | } | 4691 | } |
| 4683 | return return_type; | 4692 | return return_type; |
| ... | @@ -4700,7 +4709,7 @@ static TypeTableEntry *analyze_asm_expr(CodeGen *g, ImportTableEntry *import, Bl | ... | @@ -4700,7 +4709,7 @@ static TypeTableEntry *analyze_asm_expr(CodeGen *g, ImportTableEntry *import, Bl |
| 4700 | } | 4709 | } |
| 4701 | } else { | 4710 | } else { |
| 4702 | Buf *variable_name = &asm_output->variable_name; | 4711 | Buf *variable_name = &asm_output->variable_name; |
| 4703 | VariableTableEntry *var = find_variable(context, variable_name); | 4712 | VariableTableEntry *var = find_variable(context, variable_name, false); |
| 4704 | if (var) { | 4713 | if (var) { |
| 4705 | asm_output->variable = var; | 4714 | asm_output->variable = var; |
| 4706 | return var->type; | 4715 | return var->type; |
| ... | @@ -4719,6 +4728,13 @@ static TypeTableEntry *analyze_asm_expr(CodeGen *g, ImportTableEntry *import, Bl | ... | @@ -4719,6 +4728,13 @@ static TypeTableEntry *analyze_asm_expr(CodeGen *g, ImportTableEntry *import, Bl |
| 4719 | return return_type; | 4728 | return return_type; |
| 4720 | } | 4729 | } |
| 4721 | | 4730 | |
| | 4731 | static TypeTableEntry *analyze_goto(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| | 4732 | TypeTableEntry *expected_type, AstNode *node) |
| | 4733 | { |
| | 4734 | add_node_error(g, node, buf_sprintf("goto is broken, see https://github.com/andrewrk/zig/issues/44")); |
| | 4735 | return g->builtin_types.entry_unreachable; |
| | 4736 | } |
| | 4737 | |
| 4722 | // When you call analyze_expression, the node you pass might no longer be the child node | 4738 | // When you call analyze_expression, the node you pass might no longer be the child node |
| 4723 | // you thought it was due to implicit casting rewriting the AST. | 4739 | // you thought it was due to implicit casting rewriting the AST. |
| 4724 | static TypeTableEntry *analyze_expression(CodeGen *g, ImportTableEntry *import, BlockContext *context, | 4740 | static TypeTableEntry *analyze_expression(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| ... | @@ -4734,24 +4750,16 @@ static TypeTableEntry *analyze_expression(CodeGen *g, ImportTableEntry *import, | ... | @@ -4734,24 +4750,16 @@ static TypeTableEntry *analyze_expression(CodeGen *g, ImportTableEntry *import, |
| 4734 | case NodeTypeReturnExpr: | 4750 | case NodeTypeReturnExpr: |
| 4735 | return_type = analyze_return_expr(g, import, context, expected_type, node); | 4751 | return_type = analyze_return_expr(g, import, context, expected_type, node); |
| 4736 | break; | 4752 | break; |
| | 4753 | case NodeTypeDeferExpr: |
| | 4754 | return_type = analyze_defer_expr(g, import, context, expected_type, node); |
| | 4755 | break; |
| 4737 | case NodeTypeVariableDeclaration: | 4756 | case NodeTypeVariableDeclaration: |
| 4738 | analyze_variable_declaration(g, import, context, expected_type, node); | 4757 | analyze_variable_declaration(g, import, context, expected_type, node); |
| 4739 | return_type = g->builtin_types.entry_void; | 4758 | return_type = g->builtin_types.entry_void; |
| 4740 | break; | 4759 | break; |
| 4741 | case NodeTypeGoto: | 4760 | case NodeTypeGoto: |
| 4742 | { | 4761 | analyze_goto(g, import, context, expected_type, node); |
| 4743 | FnTableEntry *fn_table_entry = get_context_fn_entry(context); | 4762 | break; |
| 4744 | auto table_entry = fn_table_entry->label_table.maybe_get(&node->data.goto_expr.name); | | |
| 4745 | if (table_entry) { | | |
| 4746 | node->data.goto_expr.label_entry = table_entry->value; | | |
| 4747 | table_entry->value->used = true; | | |
| 4748 | } else { | | |
| 4749 | add_node_error(g, node, | | |
| 4750 | buf_sprintf("use of undeclared label '%s'", buf_ptr(&node->data.goto_expr.name))); | | |
| 4751 | } | | |
| 4752 | return_type = g->builtin_types.entry_unreachable; | | |
| 4753 | break; | | |
| 4754 | } | | |
| 4755 | case NodeTypeBreak: | 4763 | case NodeTypeBreak: |
| 4756 | return_type = analyze_break_expr(g, import, context, expected_type, node); | 4764 | return_type = analyze_break_expr(g, import, context, expected_type, node); |
| 4757 | break; | 4765 | break; |
| ... | @@ -4909,7 +4917,7 @@ static void analyze_top_level_fn_def(CodeGen *g, ImportTableEntry *import, AstNo | ... | @@ -4909,7 +4917,7 @@ static void analyze_top_level_fn_def(CodeGen *g, ImportTableEntry *import, AstNo |
| 4909 | add_node_error(g, param_decl_node, buf_sprintf("missing parameter name")); | 4917 | add_node_error(g, param_decl_node, buf_sprintf("missing parameter name")); |
| 4910 | } | 4918 | } |
| 4911 | | 4919 | |
| 4912 | VariableTableEntry *var = add_local_var(g, param_decl_node, context, &param_decl->name, type, true); | 4920 | VariableTableEntry *var = add_local_var(g, param_decl_node, import, context, &param_decl->name, type, true); |
| 4913 | var->src_arg_index = i; | 4921 | var->src_arg_index = i; |
| 4914 | param_decl_node->data.param_decl.variable = var; | 4922 | param_decl_node->data.param_decl.variable = var; |
| 4915 | | 4923 | |
| ... | @@ -4920,22 +4928,6 @@ static void analyze_top_level_fn_def(CodeGen *g, ImportTableEntry *import, AstNo | ... | @@ -4920,22 +4928,6 @@ static void analyze_top_level_fn_def(CodeGen *g, ImportTableEntry *import, AstNo |
| 4920 | TypeTableEntry *block_return_type = analyze_expression(g, import, context, expected_type, node->data.fn_def.body); | 4928 | TypeTableEntry *block_return_type = analyze_expression(g, import, context, expected_type, node->data.fn_def.body); |
| 4921 | | 4929 | |
| 4922 | node->data.fn_def.implicit_return_type = block_return_type; | 4930 | node->data.fn_def.implicit_return_type = block_return_type; |
| 4923 | | | |
| 4924 | { | | |
| 4925 | auto it = fn_table_entry->label_table.entry_iterator(); | | |
| 4926 | for (;;) { | | |
| 4927 | auto *entry = it.next(); | | |
| 4928 | if (!entry) | | |
| 4929 | break; | | |
| 4930 | | | |
| 4931 | LabelTableEntry *label_entry = entry->value; | | |
| 4932 | if (!label_entry->used) { | | |
| 4933 | add_node_error(g, label_entry->label_node, | | |
| 4934 | buf_sprintf("label '%s' defined but not used", | | |
| 4935 | buf_ptr(&label_entry->label_node->data.label.name))); | | |
| 4936 | } | | |
| 4937 | } | | |
| 4938 | } | | |
| 4939 | } | 4931 | } |
| 4940 | | 4932 | |
| 4941 | static void analyze_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) { | 4933 | static void analyze_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) { |
| ... | @@ -4964,6 +4956,7 @@ static void analyze_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode | ... | @@ -4964,6 +4956,7 @@ static void analyze_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode |
| 4964 | case NodeTypeParamDecl: | 4956 | case NodeTypeParamDecl: |
| 4965 | case NodeTypeFnDecl: | 4957 | case NodeTypeFnDecl: |
| 4966 | case NodeTypeReturnExpr: | 4958 | case NodeTypeReturnExpr: |
| | 4959 | case NodeTypeDeferExpr: |
| 4967 | case NodeTypeRoot: | 4960 | case NodeTypeRoot: |
| 4968 | case NodeTypeBlock: | 4961 | case NodeTypeBlock: |
| 4969 | case NodeTypeBinOpExpr: | 4962 | case NodeTypeBinOpExpr: |
| ... | @@ -5028,7 +5021,7 @@ static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode | ... | @@ -5028,7 +5021,7 @@ static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode |
| 5028 | Buf *name = &node->data.symbol_expr.symbol; | 5021 | Buf *name = &node->data.symbol_expr.symbol; |
| 5029 | auto table_entry = g->primitive_type_table.maybe_get(name); | 5022 | auto table_entry = g->primitive_type_table.maybe_get(name); |
| 5030 | if (!table_entry) { | 5023 | if (!table_entry) { |
| 5031 | table_entry = import->block_context->type_table.maybe_get(name); | 5024 | table_entry = import->type_table.maybe_get(name); |
| 5032 | } | 5025 | } |
| 5033 | if (!table_entry || !type_is_complete(table_entry->value)) { | 5026 | if (!table_entry || !type_is_complete(table_entry->value)) { |
| 5034 | decl_node->deps.put(name, node); | 5027 | decl_node->deps.put(name, node); |
| ... | @@ -5046,6 +5039,9 @@ static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode | ... | @@ -5046,6 +5039,9 @@ static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode |
| 5046 | case NodeTypeReturnExpr: | 5039 | case NodeTypeReturnExpr: |
| 5047 | collect_expr_decl_deps(g, import, node->data.return_expr.expr, decl_node); | 5040 | collect_expr_decl_deps(g, import, node->data.return_expr.expr, decl_node); |
| 5048 | break; | 5041 | break; |
| | 5042 | case NodeTypeDeferExpr: |
| | 5043 | collect_expr_decl_deps(g, import, node->data.defer_expr.expr, decl_node); |
| | 5044 | break; |
| 5049 | case NodeTypePrefixOpExpr: | 5045 | case NodeTypePrefixOpExpr: |
| 5050 | collect_expr_decl_deps(g, import, node->data.prefix_op_expr.primary_expr, decl_node); | 5046 | collect_expr_decl_deps(g, import, node->data.prefix_op_expr.primary_expr, decl_node); |
| 5051 | break; | 5047 | break; |
| ... | @@ -5196,7 +5192,7 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast | ... | @@ -5196,7 +5192,7 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast |
| 5196 | Buf *name = &node->data.struct_decl.name; | 5192 | Buf *name = &node->data.struct_decl.name; |
| 5197 | auto table_entry = g->primitive_type_table.maybe_get(name); | 5193 | auto table_entry = g->primitive_type_table.maybe_get(name); |
| 5198 | if (!table_entry) { | 5194 | if (!table_entry) { |
| 5199 | table_entry = import->block_context->type_table.maybe_get(name); | 5195 | table_entry = import->type_table.maybe_get(name); |
| 5200 | } | 5196 | } |
| 5201 | if (table_entry) { | 5197 | if (table_entry) { |
| 5202 | node->data.struct_decl.type_entry = table_entry->value; | 5198 | node->data.struct_decl.type_entry = table_entry->value; |
| ... | @@ -5210,20 +5206,20 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast | ... | @@ -5210,20 +5206,20 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast |
| 5210 | node->data.struct_decl.kind, node, buf_ptr(name)); | 5206 | node->data.struct_decl.kind, node, buf_ptr(name)); |
| 5211 | } | 5207 | } |
| 5212 | | 5208 | |
| 5213 | import->block_context->type_table.put(&entry->name, entry); | 5209 | import->type_table.put(&entry->name, entry); |
| 5214 | node->data.struct_decl.type_entry = entry; | 5210 | node->data.struct_decl.type_entry = entry; |
| 5215 | | 5211 | |
| 5216 | bool is_pub = (node->data.struct_decl.visib_mod != VisibModPrivate); | 5212 | bool is_pub = (node->data.struct_decl.visib_mod != VisibModPrivate); |
| 5217 | if (is_pub) { | 5213 | if (is_pub) { |
| 5218 | for (int i = 0; i < import->importers.length; i += 1) { | 5214 | for (int i = 0; i < import->importers.length; i += 1) { |
| 5219 | ImporterInfo importer = import->importers.at(i); | 5215 | ImporterInfo importer = import->importers.at(i); |
| 5220 | auto table_entry = importer.import->block_context->type_table.maybe_get(&entry->name); | 5216 | auto table_entry = importer.import->type_table.maybe_get(&entry->name); |
| 5221 | if (table_entry) { | 5217 | if (table_entry) { |
| 5222 | add_node_error(g, importer.source_node, | 5218 | add_node_error(g, importer.source_node, |
| 5223 | buf_sprintf("import of type '%s' overrides existing definition", | 5219 | buf_sprintf("import of type '%s' overrides existing definition", |
| 5224 | buf_ptr(&entry->name))); | 5220 | buf_ptr(&entry->name))); |
| 5225 | } else { | 5221 | } else { |
| 5226 | importer.import->block_context->type_table.put(&entry->name, entry); | 5222 | importer.import->type_table.put(&entry->name, entry); |
| 5227 | } | 5223 | } |
| 5228 | } | 5224 | } |
| 5229 | } | 5225 | } |
| ... | @@ -5365,6 +5361,7 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast | ... | @@ -5365,6 +5361,7 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast |
| 5365 | case NodeTypeParamDecl: | 5361 | case NodeTypeParamDecl: |
| 5366 | case NodeTypeFnDecl: | 5362 | case NodeTypeFnDecl: |
| 5367 | case NodeTypeReturnExpr: | 5363 | case NodeTypeReturnExpr: |
| | 5364 | case NodeTypeDeferExpr: |
| 5368 | case NodeTypeBlock: | 5365 | case NodeTypeBlock: |
| 5369 | case NodeTypeBinOpExpr: | 5366 | case NodeTypeBinOpExpr: |
| 5370 | case NodeTypeUnwrapErrorExpr: | 5367 | case NodeTypeUnwrapErrorExpr: |
| ... | @@ -5555,6 +5552,8 @@ Expr *get_resolved_expr(AstNode *node) { | ... | @@ -5555,6 +5552,8 @@ Expr *get_resolved_expr(AstNode *node) { |
| 5555 | switch (node->type) { | 5552 | switch (node->type) { |
| 5556 | case NodeTypeReturnExpr: | 5553 | case NodeTypeReturnExpr: |
| 5557 | return &node->data.return_expr.resolved_expr; | 5554 | return &node->data.return_expr.resolved_expr; |
| | 5555 | case NodeTypeDeferExpr: |
| | 5556 | return &node->data.defer_expr.resolved_expr; |
| 5558 | case NodeTypeBinOpExpr: | 5557 | case NodeTypeBinOpExpr: |
| 5559 | return &node->data.bin_op_expr.resolved_expr; | 5558 | return &node->data.bin_op_expr.resolved_expr; |
| 5560 | case NodeTypeUnwrapErrorExpr: | 5559 | case NodeTypeUnwrapErrorExpr: |
| ... | @@ -5653,6 +5652,7 @@ TopLevelDecl *get_resolved_top_level_decl(AstNode *node) { | ... | @@ -5653,6 +5652,7 @@ TopLevelDecl *get_resolved_top_level_decl(AstNode *node) { |
| 5653 | return &node->data.type_decl.top_level_decl; | 5652 | return &node->data.type_decl.top_level_decl; |
| 5654 | case NodeTypeNumberLiteral: | 5653 | case NodeTypeNumberLiteral: |
| 5655 | case NodeTypeReturnExpr: | 5654 | case NodeTypeReturnExpr: |
| | 5655 | case NodeTypeDeferExpr: |
| 5656 | case NodeTypeBinOpExpr: | 5656 | case NodeTypeBinOpExpr: |
| 5657 | case NodeTypeUnwrapErrorExpr: | 5657 | case NodeTypeUnwrapErrorExpr: |
| 5658 | case NodeTypePrefixOpExpr: | 5658 | case NodeTypePrefixOpExpr: |