| ... | @@ -14,6 +14,9 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import, | ... | @@ -14,6 +14,9 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import, |
| 14 | TypeTableEntry *expected_type, AstNode *node); | 14 | TypeTableEntry *expected_type, AstNode *node); |
| 15 | static TypeTableEntry *eval_const_expr(CodeGen *g, BlockContext *context, | 15 | static TypeTableEntry *eval_const_expr(CodeGen *g, BlockContext *context, |
| 16 | AstNode *node, AstNodeNumberLiteral *out_number_literal); | 16 | AstNode *node, AstNodeNumberLiteral *out_number_literal); |
| | 17 | static void collect_type_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode *type_node, DeclNode *decl_node); |
| | 18 | static VariableTableEntry *analyze_variable_declaration(CodeGen *g, ImportTableEntry *import, |
| | 19 | BlockContext *context, TypeTableEntry *expected_type, AstNode *node); |
| 17 | | 20 | |
| 18 | static AstNode *first_executing_node(AstNode *node) { | 21 | static AstNode *first_executing_node(AstNode *node) { |
| 19 | switch (node->type) { | 22 | switch (node->type) { |
| ... | @@ -438,6 +441,9 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node, ImportTableEntry | ... | @@ -438,6 +441,9 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node, ImportTableEntry |
| 438 | { | 441 | { |
| 439 | Buf *name = &node->data.type.primitive_name; | 442 | Buf *name = &node->data.type.primitive_name; |
| 440 | auto table_entry = import->type_table.maybe_get(name); | 443 | auto table_entry = import->type_table.maybe_get(name); |
| | 444 | if (!table_entry) { |
| | 445 | table_entry = g->primitive_type_table.maybe_get(name); |
| | 446 | } |
| 441 | if (table_entry) { | 447 | if (table_entry) { |
| 442 | type_node->entry = table_entry->value; | 448 | type_node->entry = table_entry->value; |
| 443 | } else { | 449 | } else { |
| ... | @@ -716,10 +722,19 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE | ... | @@ -716,10 +722,19 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE |
| 716 | } | 722 | } |
| 717 | } | 723 | } |
| 718 | | 724 | |
| 719 | static void preview_fn_def(CodeGen *g, ImportTableEntry *import, AstNode *node, TypeTableEntry *struct_type) { | 725 | static void preview_fn_proto(CodeGen *g, ImportTableEntry *import, |
| 720 | assert(node->type == NodeTypeFnDef); | 726 | AstNode *proto_node) |
| 721 | AstNode *proto_node = node->data.fn_def.fn_proto; | 727 | { |
| 722 | assert(proto_node->type == NodeTypeFnProto); | 728 | AstNode *fn_def_node = proto_node->data.fn_proto.fn_def_node; |
| | 729 | AstNode *extern_node = proto_node->data.fn_proto.extern_node; |
| | 730 | AstNode *struct_node = proto_node->data.fn_proto.struct_node; |
| | 731 | TypeTableEntry *struct_type; |
| | 732 | if (struct_node) { |
| | 733 | struct_type = struct_node->codegen_node->data.struct_decl_node.type_entry; |
| | 734 | } else { |
| | 735 | struct_type = nullptr; |
| | 736 | } |
| | 737 | |
| 723 | Buf *proto_name = &proto_node->data.fn_proto.name; | 738 | Buf *proto_name = &proto_node->data.fn_proto.name; |
| 724 | | 739 | |
| 725 | auto fn_table = struct_type ? &struct_type->data.structure.fn_table : &import->fn_table; | 740 | auto fn_table = struct_type ? &struct_type->data.structure.fn_table : &import->fn_table; |
| ... | @@ -727,69 +742,74 @@ static void preview_fn_def(CodeGen *g, ImportTableEntry *import, AstNode *node, | ... | @@ -727,69 +742,74 @@ static void preview_fn_def(CodeGen *g, ImportTableEntry *import, AstNode *node, |
| 727 | auto entry = fn_table->maybe_get(proto_name); | 742 | auto entry = fn_table->maybe_get(proto_name); |
| 728 | bool skip = false; | 743 | bool skip = false; |
| 729 | bool is_internal = (proto_node->data.fn_proto.visib_mod != VisibModExport); | 744 | bool is_internal = (proto_node->data.fn_proto.visib_mod != VisibModExport); |
| | 745 | bool is_c_compat = !is_internal || extern_node; |
| 730 | bool is_pub = (proto_node->data.fn_proto.visib_mod != VisibModPrivate); | 746 | bool is_pub = (proto_node->data.fn_proto.visib_mod != VisibModPrivate); |
| 731 | if (entry) { | 747 | if (entry) { |
| 732 | add_node_error(g, node, | 748 | add_node_error(g, proto_node, |
| 733 | buf_sprintf("redefinition of '%s'", buf_ptr(proto_name))); | 749 | buf_sprintf("redefinition of '%s'", buf_ptr(proto_name))); |
| 734 | alloc_codegen_node(node); | 750 | proto_node->codegen_node->data.fn_proto_node.skip = true; |
| 735 | node->codegen_node->data.fn_def_node.skip = true; | | |
| 736 | skip = true; | 751 | skip = true; |
| 737 | } else if (is_pub) { | 752 | } else if (is_pub) { |
| 738 | auto entry = fn_table->maybe_get(proto_name); | 753 | auto entry = fn_table->maybe_get(proto_name); |
| 739 | if (entry) { | 754 | if (entry) { |
| 740 | add_node_error(g, node, | 755 | add_node_error(g, proto_node, buf_sprintf("redefinition of '%s'", buf_ptr(proto_name))); |
| 741 | buf_sprintf("redefinition of '%s'", buf_ptr(proto_name))); | 756 | proto_node->codegen_node->data.fn_proto_node.skip = true; |
| 742 | alloc_codegen_node(node); | | |
| 743 | node->codegen_node->data.fn_def_node.skip = true; | | |
| 744 | skip = true; | 757 | skip = true; |
| 745 | } | 758 | } |
| 746 | } | 759 | } |
| 747 | if (proto_node->data.fn_proto.is_var_args) { | 760 | if (!extern_node && proto_node->data.fn_proto.is_var_args) { |
| 748 | add_node_error(g, node, | 761 | add_node_error(g, proto_node, |
| 749 | buf_sprintf("variadic arguments only allowed in extern functions")); | 762 | buf_sprintf("variadic arguments only allowed in extern functions")); |
| 750 | } | 763 | } |
| 751 | if (!skip) { | 764 | if (skip) { |
| 752 | FnTableEntry *fn_table_entry = allocate<FnTableEntry>(1); | 765 | return; |
| 753 | fn_table_entry->import_entry = import; | 766 | } |
| 754 | fn_table_entry->proto_node = proto_node; | | |
| 755 | fn_table_entry->fn_def_node = node; | | |
| 756 | fn_table_entry->internal_linkage = is_internal; | | |
| 757 | fn_table_entry->calling_convention = is_internal ? LLVMFastCallConv : LLVMCCallConv; | | |
| 758 | fn_table_entry->label_table.init(8); | | |
| 759 | fn_table_entry->member_of_struct = struct_type; | | |
| 760 | | 767 | |
| 761 | if (struct_type) { | 768 | FnTableEntry *fn_table_entry = allocate<FnTableEntry>(1); |
| 762 | buf_resize(&fn_table_entry->symbol_name, 0); | 769 | fn_table_entry->import_entry = import; |
| 763 | buf_appendf(&fn_table_entry->symbol_name, "%s_%s", | 770 | fn_table_entry->proto_node = proto_node; |
| 764 | buf_ptr(&struct_type->name), | 771 | fn_table_entry->fn_def_node = fn_def_node; |
| 765 | buf_ptr(proto_name)); | 772 | fn_table_entry->internal_linkage = !is_c_compat; |
| 766 | } else { | 773 | fn_table_entry->is_extern = extern_node; |
| 767 | buf_init_from_buf(&fn_table_entry->symbol_name, proto_name); | 774 | fn_table_entry->calling_convention = is_c_compat ? LLVMCCallConv : LLVMFastCallConv; |
| 768 | } | 775 | fn_table_entry->label_table.init(8); |
| | 776 | fn_table_entry->member_of_struct = struct_type; |
| | 777 | |
| | 778 | if (struct_type) { |
| | 779 | buf_resize(&fn_table_entry->symbol_name, 0); |
| | 780 | buf_appendf(&fn_table_entry->symbol_name, "%s_%s", |
| | 781 | buf_ptr(&struct_type->name), |
| | 782 | buf_ptr(proto_name)); |
| | 783 | } else { |
| | 784 | buf_init_from_buf(&fn_table_entry->symbol_name, proto_name); |
| | 785 | } |
| | 786 | |
| | 787 | g->fn_protos.append(fn_table_entry); |
| 769 | | 788 | |
| 770 | g->fn_protos.append(fn_table_entry); | 789 | if (!extern_node) { |
| 771 | g->fn_defs.append(fn_table_entry); | 790 | g->fn_defs.append(fn_table_entry); |
| | 791 | } |
| 772 | | 792 | |
| 773 | fn_table->put(proto_name, fn_table_entry); | 793 | fn_table->put(proto_name, fn_table_entry); |
| 774 | | 794 | |
| 775 | if (!struct_type && | 795 | if (!struct_type && |
| 776 | g->bootstrap_import && | 796 | g->bootstrap_import && |
| 777 | import == g->root_import && buf_eql_str(proto_name, "main")) | 797 | import == g->root_import && buf_eql_str(proto_name, "main")) |
| 778 | { | 798 | { |
| 779 | g->bootstrap_import->fn_table.put(proto_name, fn_table_entry); | 799 | g->bootstrap_import->fn_table.put(proto_name, fn_table_entry); |
| 780 | } | 800 | } |
| 781 | | 801 | |
| 782 | resolve_function_proto(g, proto_node, fn_table_entry, import); | 802 | resolve_function_proto(g, proto_node, fn_table_entry, import); |
| 783 | | 803 | |
| 784 | | 804 | |
| 785 | alloc_codegen_node(proto_node); | 805 | proto_node->codegen_node->data.fn_proto_node.fn_table_entry = fn_table_entry; |
| 786 | proto_node->codegen_node->data.fn_proto_node.fn_table_entry = fn_table_entry; | | |
| 787 | | 806 | |
| 788 | preview_function_labels(g, node->data.fn_def.body, fn_table_entry); | 807 | if (fn_def_node) { |
| | 808 | preview_function_labels(g, fn_def_node->data.fn_def.body, fn_table_entry); |
| 789 | } | 809 | } |
| 790 | } | 810 | } |
| 791 | | 811 | |
| 792 | static void preview_function_declarations(CodeGen *g, ImportTableEntry *import, AstNode *node) { | 812 | static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) { |
| 793 | switch (node->type) { | 813 | switch (node->type) { |
| 794 | case NodeTypeExternBlock: | 814 | case NodeTypeExternBlock: |
| 795 | for (int i = 0; i < node->data.extern_block.directives->length; i += 1) { | 815 | for (int i = 0; i < node->data.extern_block.directives->length; i += 1) { |
| ... | @@ -803,33 +823,9 @@ static void preview_function_declarations(CodeGen *g, ImportTableEntry *import, | ... | @@ -803,33 +823,9 @@ static void preview_function_declarations(CodeGen *g, ImportTableEntry *import, |
| 803 | buf_sprintf("invalid directive: '%s'", buf_ptr(name))); | 823 | buf_sprintf("invalid directive: '%s'", buf_ptr(name))); |
| 804 | } | 824 | } |
| 805 | } | 825 | } |
| 806 | | | |
| 807 | for (int fn_decl_i = 0; fn_decl_i < node->data.extern_block.fn_decls.length; fn_decl_i += 1) { | | |
| 808 | AstNode *fn_decl = node->data.extern_block.fn_decls.at(fn_decl_i); | | |
| 809 | assert(fn_decl->type == NodeTypeFnDecl); | | |
| 810 | AstNode *fn_proto = fn_decl->data.fn_decl.fn_proto; | | |
| 811 | | | |
| 812 | FnTableEntry *fn_table_entry = allocate<FnTableEntry>(1); | | |
| 813 | fn_table_entry->proto_node = fn_proto; | | |
| 814 | fn_table_entry->is_extern = true; | | |
| 815 | fn_table_entry->calling_convention = LLVMCCallConv; | | |
| 816 | fn_table_entry->import_entry = import; | | |
| 817 | fn_table_entry->label_table.init(8); | | |
| 818 | | | |
| 819 | buf_init_from_buf(&fn_table_entry->symbol_name, &fn_proto->data.fn_proto.name); | | |
| 820 | | | |
| 821 | resolve_function_proto(g, fn_proto, fn_table_entry, import); | | |
| 822 | | | |
| 823 | Buf *name = &fn_proto->data.fn_proto.name; | | |
| 824 | g->fn_protos.append(fn_table_entry); | | |
| 825 | import->fn_table.put(name, fn_table_entry); | | |
| 826 | | | |
| 827 | alloc_codegen_node(fn_proto); | | |
| 828 | fn_proto->codegen_node->data.fn_proto_node.fn_table_entry = fn_table_entry; | | |
| 829 | } | | |
| 830 | break; | 826 | break; |
| 831 | case NodeTypeFnDef: | 827 | case NodeTypeFnProto: |
| 832 | preview_fn_def(g, import, node, nullptr); | 828 | preview_fn_proto(g, import, node); |
| 833 | break; | 829 | break; |
| 834 | case NodeTypeRootExportDecl: | 830 | case NodeTypeRootExportDecl: |
| 835 | if (import == g->root_import) { | 831 | if (import == g->root_import) { |
| ... | @@ -881,95 +877,22 @@ static void preview_function_declarations(CodeGen *g, ImportTableEntry *import, | ... | @@ -881,95 +877,22 @@ static void preview_function_declarations(CodeGen *g, ImportTableEntry *import, |
| 881 | | 877 | |
| 882 | resolve_struct_type(g, import, type_entry); | 878 | resolve_struct_type(g, import, type_entry); |
| 883 | | 879 | |
| 884 | for (int i = 0; i < node->data.struct_decl.fns.length; i += 1) { | 880 | // struct member fns will get resolved independently |
| 885 | AstNode *fn_def_node = node->data.struct_decl.fns.at(i); | | |
| 886 | preview_fn_def(g, import, fn_def_node, type_entry); | | |
| 887 | } | | |
| 888 | break; | 881 | break; |
| 889 | } | 882 | } |
| 890 | case NodeTypeUse: | | |
| 891 | case NodeTypeVariableDeclaration: | 883 | case NodeTypeVariableDeclaration: |
| 892 | // nothing to do here | | |
| 893 | break; | | |
| 894 | case NodeTypeDirective: | | |
| 895 | case NodeTypeParamDecl: | | |
| 896 | case NodeTypeFnProto: | | |
| 897 | case NodeTypeType: | | |
| 898 | case NodeTypeFnDecl: | | |
| 899 | case NodeTypeReturnExpr: | | |
| 900 | case NodeTypeRoot: | | |
| 901 | case NodeTypeBlock: | | |
| 902 | case NodeTypeBinOpExpr: | | |
| 903 | case NodeTypeFnCallExpr: | | |
| 904 | case NodeTypeArrayAccessExpr: | | |
| 905 | case NodeTypeSliceExpr: | | |
| 906 | case NodeTypeNumberLiteral: | | |
| 907 | case NodeTypeStringLiteral: | | |
| 908 | case NodeTypeCharLiteral: | | |
| 909 | case NodeTypeUnreachable: | | |
| 910 | case NodeTypeVoid: | | |
| 911 | case NodeTypeBoolLiteral: | | |
| 912 | case NodeTypeNullLiteral: | | |
| 913 | case NodeTypeSymbol: | | |
| 914 | case NodeTypeCastExpr: | | |
| 915 | case NodeTypePrefixOpExpr: | | |
| 916 | case NodeTypeIfBoolExpr: | | |
| 917 | case NodeTypeIfVarExpr: | | |
| 918 | case NodeTypeWhileExpr: | | |
| 919 | case NodeTypeLabel: | | |
| 920 | case NodeTypeGoto: | | |
| 921 | case NodeTypeBreak: | | |
| 922 | case NodeTypeContinue: | | |
| 923 | case NodeTypeAsmExpr: | | |
| 924 | case NodeTypeFieldAccessExpr: | | |
| 925 | case NodeTypeStructField: | | |
| 926 | case NodeTypeStructValueExpr: | | |
| 927 | case NodeTypeStructValueField: | | |
| 928 | case NodeTypeCompilerFnExpr: | | |
| 929 | case NodeTypeCompilerFnType: | | |
| 930 | zig_unreachable(); | | |
| 931 | } | | |
| 932 | } | | |
| 933 | | | |
| 934 | static void preview_types(CodeGen *g, ImportTableEntry *import, AstNode *node) { | | |
| 935 | switch (node->type) { | | |
| 936 | case NodeTypeStructDecl: | | |
| 937 | { | 884 | { |
| 938 | alloc_codegen_node(node); | 885 | VariableTableEntry *var = analyze_variable_declaration(g, import, import->block_context, |
| 939 | StructDeclNode *struct_codegen = &node->codegen_node->data.struct_decl_node; | 886 | nullptr, node); |
| 940 | | 887 | g->global_vars.append(var); |
| 941 | Buf *name = &node->data.struct_decl.name; | | |
| 942 | auto table_entry = import->type_table.maybe_get(name); | | |
| 943 | if (table_entry) { | | |
| 944 | struct_codegen->type_entry = table_entry->value; | | |
| 945 | add_node_error(g, node, | | |
| 946 | buf_sprintf("redefinition of '%s'", buf_ptr(name))); | | |
| 947 | } else { | | |
| 948 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdStruct); | | |
| 949 | entry->type_ref = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(name)); | | |
| 950 | entry->data.structure.decl_node = node; | | |
| 951 | entry->di_type = LLVMZigCreateReplaceableCompositeType(g->dbuilder, | | |
| 952 | LLVMZigTag_DW_structure_type(), buf_ptr(&node->data.struct_decl.name), | | |
| 953 | LLVMZigFileToScope(import->di_file), import->di_file, node->line + 1); | | |
| 954 | | | |
| 955 | buf_init_from_buf(&entry->name, name); | | |
| 956 | // put off adding the debug type until we do the full struct body | | |
| 957 | // this type is incomplete until we do another pass | | |
| 958 | import->type_table.put(&entry->name, entry); | | |
| 959 | struct_codegen->type_entry = entry; | | |
| 960 | } | | |
| 961 | break; | 888 | break; |
| 962 | } | 889 | } |
| 963 | case NodeTypeExternBlock: | | |
| 964 | case NodeTypeFnDef: | | |
| 965 | case NodeTypeRootExportDecl: | | |
| 966 | case NodeTypeUse: | 890 | case NodeTypeUse: |
| 967 | case NodeTypeVariableDeclaration: | 891 | // nothing to do here |
| 968 | // nothing to do | | |
| 969 | break; | 892 | break; |
| | 893 | case NodeTypeFnDef: |
| 970 | case NodeTypeDirective: | 894 | case NodeTypeDirective: |
| 971 | case NodeTypeParamDecl: | 895 | case NodeTypeParamDecl: |
| 972 | case NodeTypeFnProto: | | |
| 973 | case NodeTypeType: | 896 | case NodeTypeType: |
| 974 | case NodeTypeFnDecl: | 897 | case NodeTypeFnDecl: |
| 975 | case NodeTypeReturnExpr: | 898 | case NodeTypeReturnExpr: |
| ... | @@ -2552,15 +2475,15 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import, | ... | @@ -2552,15 +2475,15 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import, |
| 2552 | static void analyze_top_level_fn_def(CodeGen *g, ImportTableEntry *import, AstNode *node) { | 2475 | static void analyze_top_level_fn_def(CodeGen *g, ImportTableEntry *import, AstNode *node) { |
| 2553 | assert(node->type == NodeTypeFnDef); | 2476 | assert(node->type == NodeTypeFnDef); |
| 2554 | | 2477 | |
| 2555 | if (node->codegen_node && node->codegen_node->data.fn_def_node.skip) { | 2478 | AstNode *fn_proto_node = node->data.fn_def.fn_proto; |
| | 2479 | assert(fn_proto_node->type == NodeTypeFnProto); |
| | 2480 | |
| | 2481 | if (fn_proto_node->codegen_node->data.fn_proto_node.skip) { |
| 2556 | // we detected an error with this function definition which prevents us | 2482 | // we detected an error with this function definition which prevents us |
| 2557 | // from further analyzing it. | 2483 | // from further analyzing it. |
| 2558 | return; | 2484 | return; |
| 2559 | } | 2485 | } |
| 2560 | | 2486 | |
| 2561 | AstNode *fn_proto_node = node->data.fn_def.fn_proto; | | |
| 2562 | assert(fn_proto_node->type == NodeTypeFnProto); | | |
| 2563 | | | |
| 2564 | alloc_codegen_node(node); | 2487 | alloc_codegen_node(node); |
| 2565 | BlockContext *context = new_block_context(node, import->block_context); | 2488 | BlockContext *context = new_block_context(node, import->block_context); |
| 2566 | node->codegen_node->data.fn_def_node.block_context = context; | 2489 | node->codegen_node->data.fn_def_node.block_context = context; |
| ... | @@ -2630,7 +2553,7 @@ static void analyze_top_level_fn_def(CodeGen *g, ImportTableEntry *import, AstNo | ... | @@ -2630,7 +2553,7 @@ static void analyze_top_level_fn_def(CodeGen *g, ImportTableEntry *import, AstNo |
| 2630 | } | 2553 | } |
| 2631 | } | 2554 | } |
| 2632 | | 2555 | |
| 2633 | static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import, AstNode *node) { | 2556 | static void analyze_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) { |
| 2634 | switch (node->type) { | 2557 | switch (node->type) { |
| 2635 | case NodeTypeFnDef: | 2558 | case NodeTypeFnDef: |
| 2636 | analyze_top_level_fn_def(g, import, node); | 2559 | analyze_top_level_fn_def(g, import, node); |
| ... | @@ -2732,16 +2655,332 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import, | ... | @@ -2732,16 +2655,332 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import, |
| 2732 | } | 2655 | } |
| 2733 | break; | 2656 | break; |
| 2734 | } | 2657 | } |
| | 2658 | case NodeTypeVariableDeclaration: |
| | 2659 | // handled in resolve phase |
| | 2660 | break; |
| | 2661 | case NodeTypeDirective: |
| | 2662 | case NodeTypeParamDecl: |
| | 2663 | case NodeTypeFnProto: |
| | 2664 | case NodeTypeType: |
| | 2665 | case NodeTypeFnDecl: |
| | 2666 | case NodeTypeReturnExpr: |
| | 2667 | case NodeTypeRoot: |
| | 2668 | case NodeTypeBlock: |
| | 2669 | case NodeTypeBinOpExpr: |
| | 2670 | case NodeTypeFnCallExpr: |
| | 2671 | case NodeTypeArrayAccessExpr: |
| | 2672 | case NodeTypeSliceExpr: |
| | 2673 | case NodeTypeNumberLiteral: |
| | 2674 | case NodeTypeStringLiteral: |
| | 2675 | case NodeTypeCharLiteral: |
| | 2676 | case NodeTypeUnreachable: |
| | 2677 | case NodeTypeVoid: |
| | 2678 | case NodeTypeBoolLiteral: |
| | 2679 | case NodeTypeNullLiteral: |
| | 2680 | case NodeTypeSymbol: |
| | 2681 | case NodeTypeCastExpr: |
| | 2682 | case NodeTypePrefixOpExpr: |
| | 2683 | case NodeTypeIfBoolExpr: |
| | 2684 | case NodeTypeIfVarExpr: |
| | 2685 | case NodeTypeWhileExpr: |
| | 2686 | case NodeTypeLabel: |
| | 2687 | case NodeTypeGoto: |
| | 2688 | case NodeTypeBreak: |
| | 2689 | case NodeTypeContinue: |
| | 2690 | case NodeTypeAsmExpr: |
| | 2691 | case NodeTypeFieldAccessExpr: |
| | 2692 | case NodeTypeStructField: |
| | 2693 | case NodeTypeStructValueExpr: |
| | 2694 | case NodeTypeStructValueField: |
| | 2695 | case NodeTypeCompilerFnExpr: |
| | 2696 | case NodeTypeCompilerFnType: |
| | 2697 | zig_unreachable(); |
| | 2698 | } |
| | 2699 | } |
| | 2700 | |
| | 2701 | static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode *expr_node, |
| | 2702 | DeclNode *decl_node) |
| | 2703 | { |
| | 2704 | switch (expr_node->type) { |
| | 2705 | case NodeTypeNumberLiteral: |
| | 2706 | case NodeTypeStringLiteral: |
| | 2707 | case NodeTypeCharLiteral: |
| | 2708 | case NodeTypeVoid: |
| | 2709 | case NodeTypeBoolLiteral: |
| | 2710 | case NodeTypeNullLiteral: |
| | 2711 | case NodeTypeUnreachable: |
| | 2712 | case NodeTypeGoto: |
| | 2713 | case NodeTypeBreak: |
| | 2714 | case NodeTypeContinue: |
| | 2715 | // no dependencies on other top level declarations |
| | 2716 | break; |
| | 2717 | case NodeTypeSymbol: |
| | 2718 | decl_node->deps.put(&expr_node->data.symbol, expr_node); |
| | 2719 | break; |
| | 2720 | case NodeTypeBinOpExpr: |
| | 2721 | collect_expr_decl_deps(g, import, expr_node->data.bin_op_expr.op1, decl_node); |
| | 2722 | collect_expr_decl_deps(g, import, expr_node->data.bin_op_expr.op2, decl_node); |
| | 2723 | break; |
| | 2724 | case NodeTypeReturnExpr: |
| | 2725 | collect_expr_decl_deps(g, import, expr_node->data.return_expr.expr, decl_node); |
| | 2726 | break; |
| | 2727 | case NodeTypeCastExpr: |
| | 2728 | collect_expr_decl_deps(g, import, expr_node->data.cast_expr.expr, decl_node); |
| | 2729 | collect_type_decl_deps(g, import, expr_node->data.cast_expr.type, decl_node); |
| | 2730 | break; |
| | 2731 | case NodeTypePrefixOpExpr: |
| | 2732 | collect_expr_decl_deps(g, import, expr_node->data.prefix_op_expr.primary_expr, decl_node); |
| | 2733 | break; |
| | 2734 | case NodeTypeFnCallExpr: |
| | 2735 | collect_expr_decl_deps(g, import, expr_node->data.fn_call_expr.fn_ref_expr, decl_node); |
| | 2736 | for (int i = 0; i < expr_node->data.fn_call_expr.params.length; i += 1) { |
| | 2737 | AstNode *arg_node = expr_node->data.fn_call_expr.params.at(i); |
| | 2738 | collect_expr_decl_deps(g, import, arg_node, decl_node); |
| | 2739 | } |
| | 2740 | break; |
| | 2741 | case NodeTypeArrayAccessExpr: |
| | 2742 | collect_expr_decl_deps(g, import, expr_node->data.array_access_expr.array_ref_expr, decl_node); |
| | 2743 | collect_expr_decl_deps(g, import, expr_node->data.array_access_expr.subscript, decl_node); |
| | 2744 | break; |
| | 2745 | case NodeTypeSliceExpr: |
| | 2746 | collect_expr_decl_deps(g, import, expr_node->data.slice_expr.array_ref_expr, decl_node); |
| | 2747 | collect_expr_decl_deps(g, import, expr_node->data.slice_expr.start, decl_node); |
| | 2748 | if (expr_node->data.slice_expr.end) { |
| | 2749 | collect_expr_decl_deps(g, import, expr_node->data.slice_expr.end, decl_node); |
| | 2750 | } |
| | 2751 | break; |
| | 2752 | case NodeTypeFieldAccessExpr: |
| | 2753 | collect_expr_decl_deps(g, import, expr_node->data.field_access_expr.struct_expr, decl_node); |
| | 2754 | break; |
| | 2755 | case NodeTypeIfBoolExpr: |
| | 2756 | collect_expr_decl_deps(g, import, expr_node->data.if_bool_expr.condition, decl_node); |
| | 2757 | collect_expr_decl_deps(g, import, expr_node->data.if_bool_expr.then_block, decl_node); |
| | 2758 | if (expr_node->data.if_bool_expr.else_node) { |
| | 2759 | collect_expr_decl_deps(g, import, expr_node->data.if_bool_expr.else_node, decl_node); |
| | 2760 | } |
| | 2761 | break; |
| | 2762 | case NodeTypeIfVarExpr: |
| | 2763 | if (expr_node->data.if_var_expr.var_decl.type) { |
| | 2764 | collect_type_decl_deps(g, import, expr_node->data.if_var_expr.var_decl.type, decl_node); |
| | 2765 | } |
| | 2766 | if (expr_node->data.if_var_expr.var_decl.expr) { |
| | 2767 | collect_expr_decl_deps(g, import, expr_node->data.if_var_expr.var_decl.expr, decl_node); |
| | 2768 | } |
| | 2769 | collect_expr_decl_deps(g, import, expr_node->data.if_var_expr.then_block, decl_node); |
| | 2770 | if (expr_node->data.if_bool_expr.else_node) { |
| | 2771 | collect_expr_decl_deps(g, import, expr_node->data.if_var_expr.else_node, decl_node); |
| | 2772 | } |
| | 2773 | break; |
| | 2774 | case NodeTypeWhileExpr: |
| | 2775 | collect_expr_decl_deps(g, import, expr_node->data.while_expr.condition, decl_node); |
| | 2776 | collect_expr_decl_deps(g, import, expr_node->data.while_expr.body, decl_node); |
| | 2777 | break; |
| | 2778 | case NodeTypeBlock: |
| | 2779 | for (int i = 0; i < expr_node->data.block.statements.length; i += 1) { |
| | 2780 | AstNode *stmt = expr_node->data.block.statements.at(i); |
| | 2781 | collect_expr_decl_deps(g, import, stmt, decl_node); |
| | 2782 | } |
| | 2783 | break; |
| | 2784 | case NodeTypeAsmExpr: |
| | 2785 | for (int i = 0; i < expr_node->data.asm_expr.output_list.length; i += 1) { |
| | 2786 | AsmOutput *asm_output = expr_node->data.asm_expr.output_list.at(i); |
| | 2787 | if (asm_output->return_type) { |
| | 2788 | collect_type_decl_deps(g, import, asm_output->return_type, decl_node); |
| | 2789 | } else { |
| | 2790 | decl_node->deps.put(&asm_output->variable_name, expr_node); |
| | 2791 | } |
| | 2792 | } |
| | 2793 | for (int i = 0; i < expr_node->data.asm_expr.input_list.length; i += 1) { |
| | 2794 | AsmInput *asm_input = expr_node->data.asm_expr.input_list.at(i); |
| | 2795 | collect_expr_decl_deps(g, import, asm_input->expr, decl_node); |
| | 2796 | } |
| | 2797 | break; |
| | 2798 | case NodeTypeStructValueExpr: |
| | 2799 | collect_type_decl_deps(g, import, expr_node->data.struct_val_expr.type, decl_node); |
| | 2800 | for (int i = 0; i < expr_node->data.struct_val_expr.fields.length; i += 1) { |
| | 2801 | AstNode *field_node = expr_node->data.struct_val_expr.fields.at(i); |
| | 2802 | assert(field_node->type == NodeTypeStructValueField); |
| | 2803 | collect_expr_decl_deps(g, import, field_node->data.struct_val_field.expr, decl_node); |
| | 2804 | } |
| | 2805 | break; |
| | 2806 | case NodeTypeCompilerFnExpr: |
| | 2807 | collect_expr_decl_deps(g, import, expr_node->data.compiler_fn_expr.expr, decl_node); |
| | 2808 | break; |
| | 2809 | case NodeTypeCompilerFnType: |
| | 2810 | collect_type_decl_deps(g, import, expr_node->data.compiler_fn_type.type, decl_node); |
| | 2811 | break; |
| | 2812 | case NodeTypeRoot: |
| | 2813 | case NodeTypeRootExportDecl: |
| | 2814 | case NodeTypeFnProto: |
| | 2815 | case NodeTypeFnDef: |
| | 2816 | case NodeTypeFnDecl: |
| | 2817 | case NodeTypeParamDecl: |
| | 2818 | case NodeTypeType: |
| | 2819 | case NodeTypeExternBlock: |
| | 2820 | case NodeTypeDirective: |
| | 2821 | case NodeTypeVariableDeclaration: |
| | 2822 | case NodeTypeUse: |
| | 2823 | case NodeTypeLabel: |
| | 2824 | case NodeTypeStructDecl: |
| | 2825 | case NodeTypeStructField: |
| | 2826 | case NodeTypeStructValueField: |
| | 2827 | zig_unreachable(); |
| | 2828 | } |
| | 2829 | } |
| | 2830 | |
| | 2831 | static void collect_type_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode *type_node, DeclNode *decl_node) { |
| | 2832 | assert(type_node->type == NodeTypeType); |
| | 2833 | switch (type_node->data.type.type) { |
| | 2834 | case AstNodeTypeTypePrimitive: |
| | 2835 | { |
| | 2836 | Buf *name = &type_node->data.type.primitive_name; |
| | 2837 | auto table_entry = g->primitive_type_table.maybe_get(name); |
| | 2838 | if (!table_entry) { |
| | 2839 | table_entry = import->type_table.maybe_get(name); |
| | 2840 | } |
| | 2841 | if (!table_entry) { |
| | 2842 | decl_node->deps.put(name, type_node); |
| | 2843 | } |
| | 2844 | break; |
| | 2845 | } |
| | 2846 | case AstNodeTypeTypePointer: |
| | 2847 | collect_type_decl_deps(g, import, type_node->data.type.child_type, decl_node); |
| | 2848 | break; |
| | 2849 | case AstNodeTypeTypeArray: |
| | 2850 | collect_type_decl_deps(g, import, type_node->data.type.child_type, decl_node); |
| | 2851 | if (type_node->data.type.array_size) { |
| | 2852 | collect_expr_decl_deps(g, import, type_node->data.type.array_size, decl_node); |
| | 2853 | } |
| | 2854 | break; |
| | 2855 | case AstNodeTypeTypeMaybe: |
| | 2856 | collect_type_decl_deps(g, import, type_node->data.type.child_type, decl_node); |
| | 2857 | break; |
| | 2858 | case AstNodeTypeTypeCompilerExpr: |
| | 2859 | collect_expr_decl_deps(g, import, type_node->data.type.compiler_expr, decl_node); |
| | 2860 | break; |
| | 2861 | } |
| | 2862 | } |
| | 2863 | |
| | 2864 | static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode *node) { |
| | 2865 | switch (node->type) { |
| | 2866 | case NodeTypeStructDecl: |
| | 2867 | { |
| | 2868 | alloc_codegen_node(node); |
| | 2869 | StructDeclNode *struct_codegen = &node->codegen_node->data.struct_decl_node; |
| | 2870 | |
| | 2871 | Buf *name = &node->data.struct_decl.name; |
| | 2872 | auto table_entry = import->type_table.maybe_get(name); |
| | 2873 | if (!table_entry) { |
| | 2874 | table_entry = g->primitive_type_table.maybe_get(name); |
| | 2875 | } |
| | 2876 | if (table_entry) { |
| | 2877 | struct_codegen->type_entry = table_entry->value; |
| | 2878 | add_node_error(g, node, |
| | 2879 | buf_sprintf("redefinition of '%s'", buf_ptr(name))); |
| | 2880 | } else { |
| | 2881 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdStruct); |
| | 2882 | entry->type_ref = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(name)); |
| | 2883 | entry->data.structure.decl_node = node; |
| | 2884 | entry->di_type = LLVMZigCreateReplaceableCompositeType(g->dbuilder, |
| | 2885 | LLVMZigTag_DW_structure_type(), buf_ptr(&node->data.struct_decl.name), |
| | 2886 | LLVMZigFileToScope(import->di_file), import->di_file, node->line + 1); |
| | 2887 | |
| | 2888 | buf_init_from_buf(&entry->name, name); |
| | 2889 | // put off adding the debug type until we do the full struct body |
| | 2890 | // this type is incomplete until we do another pass |
| | 2891 | import->type_table.put(&entry->name, entry); |
| | 2892 | struct_codegen->type_entry = entry; |
| | 2893 | } |
| | 2894 | |
| | 2895 | // determine which other top level declarations this struct depends on. |
| | 2896 | DeclNode *decl_node = &node->codegen_node->decl_node; |
| | 2897 | for (int i = 0; i < node->data.struct_decl.fields.length; i += 1) { |
| | 2898 | AstNode *field_node = node->data.struct_decl.fields.at(i); |
| | 2899 | AstNode *type_node = field_node->data.struct_field.type; |
| | 2900 | collect_type_decl_deps(g, import, type_node, decl_node); |
| | 2901 | } |
| | 2902 | node->codegen_node->decl_node.name = name; |
| | 2903 | node->codegen_node->decl_node.import = import; |
| | 2904 | if (decl_node->deps.size() > 0) { |
| | 2905 | g->unresolved_top_level_decls.put(name, node); |
| | 2906 | } else { |
| | 2907 | resolve_top_level_decl(g, import, node); |
| | 2908 | } |
| | 2909 | |
| | 2910 | // handle the member function definitions independently |
| | 2911 | for (int i = 0; i < node->data.struct_decl.fns.length; i += 1) { |
| | 2912 | AstNode *fn_def_node = node->data.struct_decl.fns.at(i); |
| | 2913 | AstNode *fn_proto_node = fn_def_node->data.fn_def.fn_proto; |
| | 2914 | fn_proto_node->data.fn_proto.struct_node = node; |
| | 2915 | detect_top_level_decl_deps(g, import, fn_def_node); |
| | 2916 | } |
| | 2917 | |
| | 2918 | break; |
| | 2919 | } |
| | 2920 | case NodeTypeExternBlock: |
| | 2921 | for (int fn_decl_i = 0; fn_decl_i < node->data.extern_block.fn_decls.length; fn_decl_i += 1) { |
| | 2922 | AstNode *fn_decl = node->data.extern_block.fn_decls.at(fn_decl_i); |
| | 2923 | assert(fn_decl->type == NodeTypeFnDecl); |
| | 2924 | AstNode *fn_proto = fn_decl->data.fn_decl.fn_proto; |
| | 2925 | fn_proto->data.fn_proto.extern_node = node; |
| | 2926 | detect_top_level_decl_deps(g, import, fn_proto); |
| | 2927 | } |
| | 2928 | resolve_top_level_decl(g, import, node); |
| | 2929 | break; |
| | 2930 | case NodeTypeFnDef: |
| | 2931 | node->data.fn_def.fn_proto->data.fn_proto.fn_def_node = node; |
| | 2932 | detect_top_level_decl_deps(g, import, node->data.fn_def.fn_proto); |
| | 2933 | break; |
| 2735 | case NodeTypeVariableDeclaration: | 2934 | case NodeTypeVariableDeclaration: |
| 2736 | { | 2935 | { |
| 2737 | VariableTableEntry *var = analyze_variable_declaration(g, import, import->block_context, | 2936 | // determine which other top level declarations this variable declaration depends on. |
| 2738 | nullptr, node); | 2937 | alloc_codegen_node(node); |
| 2739 | g->global_vars.append(var); | 2938 | DeclNode *decl_node = &node->codegen_node->decl_node; |
| | 2939 | if (node->data.variable_declaration.type) { |
| | 2940 | collect_type_decl_deps(g, import, node->data.variable_declaration.type, decl_node); |
| | 2941 | } |
| | 2942 | if (node->data.variable_declaration.expr) { |
| | 2943 | collect_expr_decl_deps(g, import, node->data.variable_declaration.expr, decl_node); |
| | 2944 | } |
| | 2945 | Buf *name = &node->data.variable_declaration.symbol; |
| | 2946 | node->codegen_node->decl_node.name = name; |
| | 2947 | node->codegen_node->decl_node.import = import; |
| | 2948 | if (decl_node->deps.size() > 0) { |
| | 2949 | g->unresolved_top_level_decls.put(name, node); |
| | 2950 | } else { |
| | 2951 | resolve_top_level_decl(g, import, node); |
| | 2952 | } |
| 2740 | break; | 2953 | break; |
| 2741 | } | 2954 | } |
| | 2955 | case NodeTypeFnProto: |
| | 2956 | { |
| | 2957 | // determine which other top level declarations this function prototype depends on. |
| | 2958 | alloc_codegen_node(node); |
| | 2959 | DeclNode *decl_node = &node->codegen_node->decl_node; |
| | 2960 | for (int i = 0; i < node->data.fn_proto.params.length; i += 1) { |
| | 2961 | AstNode *param_node = node->data.fn_proto.params.at(i); |
| | 2962 | assert(param_node->type == NodeTypeParamDecl); |
| | 2963 | collect_type_decl_deps(g, import, param_node->data.param_decl.type, decl_node); |
| | 2964 | } |
| | 2965 | |
| | 2966 | Buf *name = &node->data.fn_proto.name; |
| | 2967 | node->codegen_node->decl_node.name = name; |
| | 2968 | node->codegen_node->decl_node.import = import; |
| | 2969 | if (decl_node->deps.size() > 0) { |
| | 2970 | g->unresolved_top_level_decls.put(name, node); |
| | 2971 | } else { |
| | 2972 | resolve_top_level_decl(g, import, node); |
| | 2973 | } |
| | 2974 | break; |
| | 2975 | } |
| | 2976 | case NodeTypeRootExportDecl: |
| | 2977 | resolve_top_level_decl(g, import, node); |
| | 2978 | break; |
| | 2979 | case NodeTypeUse: |
| | 2980 | // nothing to do |
| | 2981 | break; |
| 2742 | case NodeTypeDirective: | 2982 | case NodeTypeDirective: |
| 2743 | case NodeTypeParamDecl: | 2983 | case NodeTypeParamDecl: |
| 2744 | case NodeTypeFnProto: | | |
| 2745 | case NodeTypeType: | 2984 | case NodeTypeType: |
| 2746 | case NodeTypeFnDecl: | 2985 | case NodeTypeFnDecl: |
| 2747 | case NodeTypeReturnExpr: | 2986 | case NodeTypeReturnExpr: |
| ... | @@ -2779,24 +3018,69 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import, | ... | @@ -2779,24 +3018,69 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import, |
| 2779 | } | 3018 | } |
| 2780 | } | 3019 | } |
| 2781 | | 3020 | |
| 2782 | static void find_function_declarations_root(CodeGen *g, ImportTableEntry *import, AstNode *node) { | 3021 | static void recursive_resolve_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) { |
| 2783 | assert(node->type == NodeTypeRoot); | 3022 | auto it = node->codegen_node->decl_node.deps.entry_iterator(); |
| | 3023 | for (;;) { |
| | 3024 | auto *entry = it.next(); |
| | 3025 | if (!entry) |
| | 3026 | break; |
| 2784 | | 3027 | |
| 2785 | for (int i = 0; i < node->data.root.top_level_decls.length; i += 1) { | 3028 | auto unresolved_entry = g->unresolved_top_level_decls.maybe_get(entry->key); |
| 2786 | AstNode *child = node->data.root.top_level_decls.at(i); | 3029 | if (!unresolved_entry) { |
| 2787 | preview_function_declarations(g, import, child); | 3030 | continue; |
| | 3031 | } |
| | 3032 | |
| | 3033 | AstNode *child_node = unresolved_entry->value; |
| | 3034 | |
| | 3035 | if (child_node->codegen_node->decl_node.in_current_deps) { |
| | 3036 | zig_panic("TODO infinite top level decl loop"); |
| | 3037 | } |
| | 3038 | |
| | 3039 | // set temporary flag |
| | 3040 | child_node->codegen_node->decl_node.in_current_deps = true; |
| | 3041 | |
| | 3042 | recursive_resolve_decl(g, child_node->codegen_node->decl_node.import, child_node); |
| | 3043 | |
| | 3044 | // unset temporary flag |
| | 3045 | child_node->codegen_node->decl_node.in_current_deps = false; |
| 2788 | } | 3046 | } |
| 2789 | | 3047 | |
| | 3048 | resolve_top_level_decl(g, import, node); |
| | 3049 | g->unresolved_top_level_decls.remove(node->codegen_node->decl_node.name); |
| 2790 | } | 3050 | } |
| 2791 | | 3051 | |
| 2792 | static void preview_types_root(CodeGen *g, ImportTableEntry *import, AstNode *node) { | 3052 | static void resolve_top_level_declarations_root(CodeGen *g, ImportTableEntry *import, AstNode *node) { |
| 2793 | assert(node->type == NodeTypeRoot); | 3053 | assert(node->type == NodeTypeRoot); |
| 2794 | | 3054 | |
| 2795 | for (int i = 0; i < node->data.root.top_level_decls.length; i += 1) { | 3055 | for (int i = 0; i < node->data.root.top_level_decls.length; i += 1) { |
| 2796 | AstNode *child = node->data.root.top_level_decls.at(i); | 3056 | AstNode *child = node->data.root.top_level_decls.at(i); |
| 2797 | preview_types(g, import, child); | 3057 | detect_top_level_decl_deps(g, import, child); |
| 2798 | } | 3058 | } |
| 2799 | | 3059 | |
| | 3060 | while (g->unresolved_top_level_decls.size() > 0) { |
| | 3061 | // for the sake of determinism, find the element with the lowest |
| | 3062 | // insert index and resolve that one. |
| | 3063 | AstNode *decl_node = nullptr; |
| | 3064 | auto it = g->unresolved_top_level_decls.entry_iterator(); |
| | 3065 | for (;;) { |
| | 3066 | auto *entry = it.next(); |
| | 3067 | if (!entry) |
| | 3068 | break; |
| | 3069 | |
| | 3070 | AstNode *this_node = entry->value; |
| | 3071 | if (!decl_node || this_node->create_index < decl_node->create_index) { |
| | 3072 | decl_node = this_node; |
| | 3073 | } |
| | 3074 | |
| | 3075 | } |
| | 3076 | // set temporary flag |
| | 3077 | decl_node->codegen_node->decl_node.in_current_deps = true; |
| | 3078 | |
| | 3079 | recursive_resolve_decl(g, decl_node->codegen_node->decl_node.import, decl_node); |
| | 3080 | |
| | 3081 | // unset temporary flag |
| | 3082 | decl_node->codegen_node->decl_node.in_current_deps = false; |
| | 3083 | } |
| 2800 | } | 3084 | } |
| 2801 | | 3085 | |
| 2802 | static void analyze_top_level_decls_root(CodeGen *g, ImportTableEntry *import, AstNode *node) { | 3086 | static void analyze_top_level_decls_root(CodeGen *g, ImportTableEntry *import, AstNode *node) { |
| ... | @@ -2804,7 +3088,7 @@ static void analyze_top_level_decls_root(CodeGen *g, ImportTableEntry *import, A | ... | @@ -2804,7 +3088,7 @@ static void analyze_top_level_decls_root(CodeGen *g, ImportTableEntry *import, A |
| 2804 | | 3088 | |
| 2805 | for (int i = 0; i < node->data.root.top_level_decls.length; i += 1) { | 3089 | for (int i = 0; i < node->data.root.top_level_decls.length; i += 1) { |
| 2806 | AstNode *child = node->data.root.top_level_decls.at(i); | 3090 | AstNode *child = node->data.root.top_level_decls.at(i); |
| 2807 | analyze_top_level_declaration(g, import, child); | 3091 | analyze_top_level_decl(g, import, child); |
| 2808 | } | 3092 | } |
| 2809 | } | 3093 | } |
| 2810 | | 3094 | |
| ... | @@ -2817,21 +3101,9 @@ void semantic_analyze(CodeGen *g) { | ... | @@ -2817,21 +3101,9 @@ void semantic_analyze(CodeGen *g) { |
| 2817 | break; | 3101 | break; |
| 2818 | | 3102 | |
| 2819 | ImportTableEntry *import = entry->value; | 3103 | ImportTableEntry *import = entry->value; |
| 2820 | preview_types_root(g, import, import->root); | 3104 | resolve_top_level_declarations_root(g, import, import->root); |
| 2821 | } | | |
| 2822 | } | | |
| 2823 | { | | |
| 2824 | auto it = g->import_table.entry_iterator(); | | |
| 2825 | for (;;) { | | |
| 2826 | auto *entry = it.next(); | | |
| 2827 | if (!entry) | | |
| 2828 | break; | | |
| 2829 | | | |
| 2830 | ImportTableEntry *import = entry->value; | | |
| 2831 | find_function_declarations_root(g, import, import->root); | | |
| 2832 | } | 3105 | } |
| 2833 | } | 3106 | } |
| 2834 | | | |
| 2835 | { | 3107 | { |
| 2836 | auto it = g->import_table.entry_iterator(); | 3108 | auto it = g->import_table.entry_iterator(); |
| 2837 | for (;;) { | 3109 | for (;;) { |
| ... | @@ -2844,7 +3116,6 @@ void semantic_analyze(CodeGen *g) { | ... | @@ -2844,7 +3116,6 @@ void semantic_analyze(CodeGen *g) { |
| 2844 | } | 3116 | } |
| 2845 | } | 3117 | } |
| 2846 | | 3118 | |
| 2847 | | | |
| 2848 | if (!g->root_out_name) { | 3119 | if (!g->root_out_name) { |
| 2849 | add_node_error(g, g->root_import->root, | 3120 | add_node_error(g, g->root_import->root, |
| 2850 | buf_sprintf("missing export declaration and output name not provided")); | 3121 | buf_sprintf("missing export declaration and output name not provided")); |
| ... | @@ -2857,5 +3128,6 @@ void semantic_analyze(CodeGen *g) { | ... | @@ -2857,5 +3128,6 @@ void semantic_analyze(CodeGen *g) { |
| 2857 | void alloc_codegen_node(AstNode *node) { | 3128 | void alloc_codegen_node(AstNode *node) { |
| 2858 | assert(!node->codegen_node); | 3129 | assert(!node->codegen_node); |
| 2859 | node->codegen_node = allocate<CodeGenNode>(1); | 3130 | node->codegen_node = allocate<CodeGenNode>(1); |
| | 3131 | node->codegen_node->decl_node.deps.init(1); |
| 2860 | } | 3132 | } |
| 2861 | | 3133 | |