authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-09 23:49:22-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-09 23:49:22-07:00
log1fe1235e14cd599c1b3a6f079670b7cb7ea270d2
tree87e7bf3db7b96ccf27d4e23591460b7b1c21a3a9
parent6d9119fcd91cd01d658180d7fa5e4c8c203ba3db

order-independent declarations

code constructs and traverses a dependency graph in a deterministic order.

6 files changed, 498 insertions(+), 196 deletions(-)

src/analyze.cpp+451-179
......@@ -14,6 +14,9 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
1414 TypeTableEntry *expected_type, AstNode *node);
1515static TypeTableEntry *eval_const_expr(CodeGen *g, BlockContext *context,
1616 AstNode *node, AstNodeNumberLiteral *out_number_literal);
17static void collect_type_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode *type_node, DeclNode *decl_node);
18static VariableTableEntry *analyze_variable_declaration(CodeGen *g, ImportTableEntry *import,
19 BlockContext *context, TypeTableEntry *expected_type, AstNode *node);
1720
1821static AstNode *first_executing_node(AstNode *node) {
1922 switch (node->type) {
......@@ -438,6 +441,9 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node, ImportTableEntry
438441 {
439442 Buf *name = &node->data.type.primitive_name;
440443 auto table_entry = import->type_table.maybe_get(name);
444 if (!table_entry) {
445 table_entry = g->primitive_type_table.maybe_get(name);
446 }
441447 if (table_entry) {
442448 type_node->entry = table_entry->value;
443449 } else {
......@@ -716,10 +722,19 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE
716722 }
717723}
718724
719static void preview_fn_def(CodeGen *g, ImportTableEntry *import, AstNode *node, TypeTableEntry *struct_type) {
720 assert(node->type == NodeTypeFnDef);
721 AstNode *proto_node = node->data.fn_def.fn_proto;
722 assert(proto_node->type == NodeTypeFnProto);
725static void preview_fn_proto(CodeGen *g, ImportTableEntry *import,
726 AstNode *proto_node)
727{
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
723738 Buf *proto_name = &proto_node->data.fn_proto.name;
724739
725740 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,
727742 auto entry = fn_table->maybe_get(proto_name);
728743 bool skip = false;
729744 bool is_internal = (proto_node->data.fn_proto.visib_mod != VisibModExport);
745 bool is_c_compat = !is_internal || extern_node;
730746 bool is_pub = (proto_node->data.fn_proto.visib_mod != VisibModPrivate);
731747 if (entry) {
732 add_node_error(g, node,
748 add_node_error(g, proto_node,
733749 buf_sprintf("redefinition of '%s'", buf_ptr(proto_name)));
734 alloc_codegen_node(node);
735 node->codegen_node->data.fn_def_node.skip = true;
750 proto_node->codegen_node->data.fn_proto_node.skip = true;
736751 skip = true;
737752 } else if (is_pub) {
738753 auto entry = fn_table->maybe_get(proto_name);
739754 if (entry) {
740 add_node_error(g, node,
741 buf_sprintf("redefinition of '%s'", buf_ptr(proto_name)));
742 alloc_codegen_node(node);
743 node->codegen_node->data.fn_def_node.skip = true;
755 add_node_error(g, proto_node, buf_sprintf("redefinition of '%s'", buf_ptr(proto_name)));
756 proto_node->codegen_node->data.fn_proto_node.skip = true;
744757 skip = true;
745758 }
746759 }
747 if (proto_node->data.fn_proto.is_var_args) {
748 add_node_error(g, node,
760 if (!extern_node && proto_node->data.fn_proto.is_var_args) {
761 add_node_error(g, proto_node,
749762 buf_sprintf("variadic arguments only allowed in extern functions"));
750763 }
751 if (!skip) {
752 FnTableEntry *fn_table_entry = allocate<FnTableEntry>(1);
753 fn_table_entry->import_entry = import;
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;
764 if (skip) {
765 return;
766 }
760767
761 if (struct_type) {
762 buf_resize(&fn_table_entry->symbol_name, 0);
763 buf_appendf(&fn_table_entry->symbol_name, "%s_%s",
764 buf_ptr(&struct_type->name),
765 buf_ptr(proto_name));
766 } else {
767 buf_init_from_buf(&fn_table_entry->symbol_name, proto_name);
768 }
768 FnTableEntry *fn_table_entry = allocate<FnTableEntry>(1);
769 fn_table_entry->import_entry = import;
770 fn_table_entry->proto_node = proto_node;
771 fn_table_entry->fn_def_node = fn_def_node;
772 fn_table_entry->internal_linkage = !is_c_compat;
773 fn_table_entry->is_extern = extern_node;
774 fn_table_entry->calling_convention = is_c_compat ? LLVMCCallConv : LLVMFastCallConv;
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);
769788
770 g->fn_protos.append(fn_table_entry);
789 if (!extern_node) {
771790 g->fn_defs.append(fn_table_entry);
791 }
772792
773 fn_table->put(proto_name, fn_table_entry);
793 fn_table->put(proto_name, fn_table_entry);
774794
775 if (!struct_type &&
776 g->bootstrap_import &&
777 import == g->root_import && buf_eql_str(proto_name, "main"))
778 {
779 g->bootstrap_import->fn_table.put(proto_name, fn_table_entry);
780 }
795 if (!struct_type &&
796 g->bootstrap_import &&
797 import == g->root_import && buf_eql_str(proto_name, "main"))
798 {
799 g->bootstrap_import->fn_table.put(proto_name, fn_table_entry);
800 }
781801
782 resolve_function_proto(g, proto_node, fn_table_entry, import);
802 resolve_function_proto(g, proto_node, fn_table_entry, import);
783803
784804
785 alloc_codegen_node(proto_node);
786 proto_node->codegen_node->data.fn_proto_node.fn_table_entry = fn_table_entry;
805 proto_node->codegen_node->data.fn_proto_node.fn_table_entry = fn_table_entry;
787806
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);
789809 }
790810}
791811
792static void preview_function_declarations(CodeGen *g, ImportTableEntry *import, AstNode *node) {
812static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) {
793813 switch (node->type) {
794814 case NodeTypeExternBlock:
795815 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,
803823 buf_sprintf("invalid directive: '%s'", buf_ptr(name)));
804824 }
805825 }
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 }
830826 break;
831 case NodeTypeFnDef:
832 preview_fn_def(g, import, node, nullptr);
827 case NodeTypeFnProto:
828 preview_fn_proto(g, import, node);
833829 break;
834830 case NodeTypeRootExportDecl:
835831 if (import == g->root_import) {
......@@ -881,95 +877,22 @@ static void preview_function_declarations(CodeGen *g, ImportTableEntry *import,
881877
882878 resolve_struct_type(g, import, type_entry);
883879
884 for (int i = 0; i < node->data.struct_decl.fns.length; i += 1) {
885 AstNode *fn_def_node = node->data.struct_decl.fns.at(i);
886 preview_fn_def(g, import, fn_def_node, type_entry);
887 }
880 // struct member fns will get resolved independently
888881 break;
889882 }
890 case NodeTypeUse:
891883 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
934static void preview_types(CodeGen *g, ImportTableEntry *import, AstNode *node) {
935 switch (node->type) {
936 case NodeTypeStructDecl:
937884 {
938 alloc_codegen_node(node);
939 StructDeclNode *struct_codegen = &node->codegen_node->data.struct_decl_node;
940
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 }
885 VariableTableEntry *var = analyze_variable_declaration(g, import, import->block_context,
886 nullptr, node);
887 g->global_vars.append(var);
961888 break;
962889 }
963 case NodeTypeExternBlock:
964 case NodeTypeFnDef:
965 case NodeTypeRootExportDecl:
966890 case NodeTypeUse:
967 case NodeTypeVariableDeclaration:
968 // nothing to do
891 // nothing to do here
969892 break;
893 case NodeTypeFnDef:
970894 case NodeTypeDirective:
971895 case NodeTypeParamDecl:
972 case NodeTypeFnProto:
973896 case NodeTypeType:
974897 case NodeTypeFnDecl:
975898 case NodeTypeReturnExpr:
......@@ -2552,15 +2475,15 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
25522475static void analyze_top_level_fn_def(CodeGen *g, ImportTableEntry *import, AstNode *node) {
25532476 assert(node->type == NodeTypeFnDef);
25542477
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) {
25562482 // we detected an error with this function definition which prevents us
25572483 // from further analyzing it.
25582484 return;
25592485 }
25602486
2561 AstNode *fn_proto_node = node->data.fn_def.fn_proto;
2562 assert(fn_proto_node->type == NodeTypeFnProto);
2563
25642487 alloc_codegen_node(node);
25652488 BlockContext *context = new_block_context(node, import->block_context);
25662489 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
26302553 }
26312554}
26322555
2633static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import, AstNode *node) {
2556static void analyze_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) {
26342557 switch (node->type) {
26352558 case NodeTypeFnDef:
26362559 analyze_top_level_fn_def(g, import, node);
......@@ -2732,16 +2655,332 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import,
27322655 }
27332656 break;
27342657 }
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
2701static 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
2831static 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
2864static 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;
27352934 case NodeTypeVariableDeclaration:
27362935 {
2737 VariableTableEntry *var = analyze_variable_declaration(g, import, import->block_context,
2738 nullptr, node);
2739 g->global_vars.append(var);
2936 // determine which other top level declarations this variable declaration depends on.
2937 alloc_codegen_node(node);
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 }
27402953 break;
27412954 }
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;
27422982 case NodeTypeDirective:
27432983 case NodeTypeParamDecl:
2744 case NodeTypeFnProto:
27452984 case NodeTypeType:
27462985 case NodeTypeFnDecl:
27472986 case NodeTypeReturnExpr:
......@@ -2779,24 +3018,69 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import,
27793018 }
27803019}
27813020
2782static void find_function_declarations_root(CodeGen *g, ImportTableEntry *import, AstNode *node) {
2783 assert(node->type == NodeTypeRoot);
3021static void recursive_resolve_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) {
3022 auto it = node->codegen_node->decl_node.deps.entry_iterator();
3023 for (;;) {
3024 auto *entry = it.next();
3025 if (!entry)
3026 break;
27843027
2785 for (int i = 0; i < node->data.root.top_level_decls.length; i += 1) {
2786 AstNode *child = node->data.root.top_level_decls.at(i);
2787 preview_function_declarations(g, import, child);
3028 auto unresolved_entry = g->unresolved_top_level_decls.maybe_get(entry->key);
3029 if (!unresolved_entry) {
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;
27883046 }
27893047
3048 resolve_top_level_decl(g, import, node);
3049 g->unresolved_top_level_decls.remove(node->codegen_node->decl_node.name);
27903050}
27913051
2792static void preview_types_root(CodeGen *g, ImportTableEntry *import, AstNode *node) {
3052static void resolve_top_level_declarations_root(CodeGen *g, ImportTableEntry *import, AstNode *node) {
27933053 assert(node->type == NodeTypeRoot);
27943054
27953055 for (int i = 0; i < node->data.root.top_level_decls.length; i += 1) {
27963056 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);
27983058 }
27993059
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 }
28003084}
28013085
28023086static 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
28043088
28053089 for (int i = 0; i < node->data.root.top_level_decls.length; i += 1) {
28063090 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);
28083092 }
28093093}
28103094
......@@ -2817,21 +3101,9 @@ void semantic_analyze(CodeGen *g) {
28173101 break;
28183102
28193103 ImportTableEntry *import = entry->value;
2820 preview_types_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);
3104 resolve_top_level_declarations_root(g, import, import->root);
28323105 }
28333106 }
2834
28353107 {
28363108 auto it = g->import_table.entry_iterator();
28373109 for (;;) {
......@@ -2844,7 +3116,6 @@ void semantic_analyze(CodeGen *g) {
28443116 }
28453117 }
28463118
2847
28483119 if (!g->root_out_name) {
28493120 add_node_error(g, g->root_import->root,
28503121 buf_sprintf("missing export declaration and output name not provided"));
......@@ -2857,5 +3128,6 @@ void semantic_analyze(CodeGen *g) {
28573128void alloc_codegen_node(AstNode *node) {
28583129 assert(!node->codegen_node);
28593130 node->codegen_node = allocate<CodeGenNode>(1);
3131 node->codegen_node->decl_node.deps.init(1);
28603132}
28613133
src/analyze.hpp+15-1
......@@ -178,6 +178,10 @@ struct CodeGen {
178178 HashMap<Buf *, bool, buf_hash, buf_eql_buf> link_table;
179179 HashMap<Buf *, ImportTableEntry *, buf_hash, buf_eql_buf> import_table;
180180 HashMap<Buf *, BuiltinFnEntry *, buf_hash, buf_eql_buf> builtin_fn_table;
181 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> primitive_type_table;
182 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> unresolved_top_level_decls;
183
184 uint32_t next_unresolved_index;
181185
182186 struct {
183187 TypeTableEntry *entry_bool;
......@@ -270,12 +274,12 @@ struct TypeNode {
270274
271275struct FnProtoNode {
272276 FnTableEntry *fn_table_entry;
277 bool skip;
273278};
274279
275280struct FnDefNode {
276281 TypeTableEntry *implicit_return_type;
277282 BlockContext *block_context;
278 bool skip;
279283};
280284
281285
......@@ -364,6 +368,15 @@ struct FnCallNode {
364368 BuiltinFnEntry *builtin_fn;
365369};
366370
371struct DeclNode {
372 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> deps;
373 Buf *name;
374 ImportTableEntry *import;
375 // set this flag temporarily to detect infinite loops
376 bool in_current_deps;
377};
378
379// TODO get rid of this structure and put the data directly in the appropriate AST node
367380struct CodeGenNode {
368381 union {
369382 TypeNode type_node; // for NodeTypeType
......@@ -388,6 +401,7 @@ struct CodeGenNode {
388401 FnCallNode fn_call_node; // for NodeTypeFnCallExpr
389402 } data;
390403 ExprNode expr_node; // for all the expression nodes
404 DeclNode decl_node; // for all top level decls
391405};
392406
393407void semantic_analyze(CodeGen *g);
src/codegen.cpp+17-15
......@@ -23,6 +23,8 @@ CodeGen *codegen_create(Buf *root_source_dir) {
2323 g->link_table.init(32);
2424 g->import_table.init(32);
2525 g->builtin_fn_table.init(32);
26 g->primitive_type_table.init(32);
27 g->unresolved_top_level_decls.init(32);
2628 g->build_type = CodeGenBuildTypeDebug;
2729 g->root_source_dir = root_source_dir;
2830
......@@ -2109,6 +2111,7 @@ static void define_builtin_types(CodeGen *g) {
21092111 entry->size_in_bits, entry->align_in_bits,
21102112 LLVMZigEncoding_DW_ATE_unsigned());
21112113 g->builtin_types.entry_bool = entry;
2114 g->primitive_type_table.put(&entry->name, entry);
21122115 }
21132116 {
21142117 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
......@@ -2120,6 +2123,7 @@ static void define_builtin_types(CodeGen *g) {
21202123 entry->size_in_bits, entry->align_in_bits,
21212124 LLVMZigEncoding_DW_ATE_unsigned());
21222125 g->builtin_types.entry_u8 = entry;
2126 g->primitive_type_table.put(&entry->name, entry);
21232127 }
21242128 {
21252129 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
......@@ -2132,6 +2136,7 @@ static void define_builtin_types(CodeGen *g) {
21322136 entry->size_in_bits, entry->align_in_bits,
21332137 LLVMZigEncoding_DW_ATE_unsigned());
21342138 g->builtin_types.entry_u16 = entry;
2139 g->primitive_type_table.put(&entry->name, entry);
21352140 }
21362141 {
21372142 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
......@@ -2144,6 +2149,7 @@ static void define_builtin_types(CodeGen *g) {
21442149 entry->size_in_bits, entry->align_in_bits,
21452150 LLVMZigEncoding_DW_ATE_unsigned());
21462151 g->builtin_types.entry_u32 = entry;
2152 g->primitive_type_table.put(&entry->name, entry);
21472153 }
21482154 {
21492155 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
......@@ -2156,6 +2162,7 @@ static void define_builtin_types(CodeGen *g) {
21562162 entry->size_in_bits, entry->align_in_bits,
21572163 LLVMZigEncoding_DW_ATE_unsigned());
21582164 g->builtin_types.entry_u64 = entry;
2165 g->primitive_type_table.put(&entry->name, entry);
21592166 }
21602167 g->builtin_types.entry_c_string_literal = get_pointer_to_type(g, g->builtin_types.entry_u8, true, false);
21612168 {
......@@ -2169,6 +2176,7 @@ static void define_builtin_types(CodeGen *g) {
21692176 entry->size_in_bits, entry->align_in_bits,
21702177 LLVMZigEncoding_DW_ATE_signed());
21712178 g->builtin_types.entry_i8 = entry;
2179 g->primitive_type_table.put(&entry->name, entry);
21722180 }
21732181 {
21742182 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
......@@ -2181,6 +2189,7 @@ static void define_builtin_types(CodeGen *g) {
21812189 entry->size_in_bits, entry->align_in_bits,
21822190 LLVMZigEncoding_DW_ATE_signed());
21832191 g->builtin_types.entry_i16 = entry;
2192 g->primitive_type_table.put(&entry->name, entry);
21842193 }
21852194 {
21862195 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
......@@ -2193,6 +2202,7 @@ static void define_builtin_types(CodeGen *g) {
21932202 entry->size_in_bits, entry->align_in_bits,
21942203 LLVMZigEncoding_DW_ATE_signed());
21952204 g->builtin_types.entry_i32 = entry;
2205 g->primitive_type_table.put(&entry->name, entry);
21962206 }
21972207 {
21982208 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
......@@ -2205,6 +2215,7 @@ static void define_builtin_types(CodeGen *g) {
22052215 entry->size_in_bits, entry->align_in_bits,
22062216 LLVMZigEncoding_DW_ATE_signed());
22072217 g->builtin_types.entry_i64 = entry;
2218 g->primitive_type_table.put(&entry->name, entry);
22082219 }
22092220 {
22102221 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
......@@ -2217,6 +2228,7 @@ static void define_builtin_types(CodeGen *g) {
22172228 entry->size_in_bits, entry->align_in_bits,
22182229 LLVMZigEncoding_DW_ATE_signed());
22192230 g->builtin_types.entry_isize = entry;
2231 g->primitive_type_table.put(&entry->name, entry);
22202232 }
22212233 {
22222234 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
......@@ -2229,6 +2241,7 @@ static void define_builtin_types(CodeGen *g) {
22292241 entry->size_in_bits, entry->align_in_bits,
22302242 LLVMZigEncoding_DW_ATE_unsigned());
22312243 g->builtin_types.entry_usize = entry;
2244 g->primitive_type_table.put(&entry->name, entry);
22322245 }
22332246 {
22342247 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);
......@@ -2240,6 +2253,7 @@ static void define_builtin_types(CodeGen *g) {
22402253 entry->size_in_bits, entry->align_in_bits,
22412254 LLVMZigEncoding_DW_ATE_float());
22422255 g->builtin_types.entry_f32 = entry;
2256 g->primitive_type_table.put(&entry->name, entry);
22432257 }
22442258 {
22452259 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);
......@@ -2251,6 +2265,7 @@ static void define_builtin_types(CodeGen *g) {
22512265 entry->size_in_bits, entry->align_in_bits,
22522266 LLVMZigEncoding_DW_ATE_float());
22532267 g->builtin_types.entry_f64 = entry;
2268 g->primitive_type_table.put(&entry->name, entry);
22542269 }
22552270 {
22562271 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdVoid);
......@@ -2260,6 +2275,7 @@ static void define_builtin_types(CodeGen *g) {
22602275 entry->size_in_bits, entry->align_in_bits,
22612276 LLVMZigEncoding_DW_ATE_unsigned());
22622277 g->builtin_types.entry_void = entry;
2278 g->primitive_type_table.put(&entry->name, entry);
22632279 }
22642280 {
22652281 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdUnreachable);
......@@ -2267,6 +2283,7 @@ static void define_builtin_types(CodeGen *g) {
22672283 buf_init_from_str(&entry->name, "unreachable");
22682284 entry->di_type = g->builtin_types.entry_void->di_type;
22692285 g->builtin_types.entry_unreachable = entry;
2286 g->primitive_type_table.put(&entry->name, entry);
22702287 }
22712288}
22722289
......@@ -2506,21 +2523,6 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *abs_full_path,
25062523 import_entry->path = full_path;
25072524 import_entry->fn_table.init(32);
25082525 import_entry->type_table.init(32);
2509 import_entry->type_table.put(&g->builtin_types.entry_bool->name, g->builtin_types.entry_bool);
2510 import_entry->type_table.put(&g->builtin_types.entry_u8->name, g->builtin_types.entry_u8);
2511 import_entry->type_table.put(&g->builtin_types.entry_u16->name, g->builtin_types.entry_u16);
2512 import_entry->type_table.put(&g->builtin_types.entry_u32->name, g->builtin_types.entry_u32);
2513 import_entry->type_table.put(&g->builtin_types.entry_u64->name, g->builtin_types.entry_u64);
2514 import_entry->type_table.put(&g->builtin_types.entry_i8->name, g->builtin_types.entry_i8);
2515 import_entry->type_table.put(&g->builtin_types.entry_i16->name, g->builtin_types.entry_i16);
2516 import_entry->type_table.put(&g->builtin_types.entry_i32->name, g->builtin_types.entry_i32);
2517 import_entry->type_table.put(&g->builtin_types.entry_i64->name, g->builtin_types.entry_i64);
2518 import_entry->type_table.put(&g->builtin_types.entry_isize->name, g->builtin_types.entry_isize);
2519 import_entry->type_table.put(&g->builtin_types.entry_usize->name, g->builtin_types.entry_usize);
2520 import_entry->type_table.put(&g->builtin_types.entry_f32->name, g->builtin_types.entry_f32);
2521 import_entry->type_table.put(&g->builtin_types.entry_f64->name, g->builtin_types.entry_f64);
2522 import_entry->type_table.put(&g->builtin_types.entry_void->name, g->builtin_types.entry_void);
2523 import_entry->type_table.put(&g->builtin_types.entry_unreachable->name, g->builtin_types.entry_unreachable);
25242526
25252527 import_entry->root = ast_parse(source_code, tokenization.tokens, import_entry, g->err_color);
25262528 assert(import_entry->root);
src/parser.cpp+3
......@@ -457,6 +457,7 @@ struct ParseContext {
457457 ZigList<AstNode *> *directive_list;
458458 ImportTableEntry *owner;
459459 ErrColor err_color;
460 uint32_t next_create_index;
460461};
461462
462463__attribute__ ((format (printf, 4, 5)))
......@@ -512,6 +513,8 @@ static AstNode *ast_create_node_no_line_info(ParseContext *pc, NodeType type) {
512513 AstNode *node = allocate<AstNode>(1);
513514 node->type = type;
514515 node->owner = pc->owner;
516 node->create_index = pc->next_create_index;
517 pc->next_create_index += 1;
515518 return node;
516519}
517520
src/parser.hpp+11
......@@ -80,6 +80,16 @@ struct AstNodeFnProto {
8080 ZigList<AstNode *> params;
8181 AstNode *return_type;
8282 bool is_var_args;
83
84 // the extern block this fn proto is inside. can be null.
85 // populated by semantic analyzer.
86 AstNode *extern_node;
87 // the struct decl node this fn proto is inside. can be null.
88 // populated by semantic analyzer.
89 AstNode *struct_node;
90 // the function definition this fn proto is inside. can be null.
91 // populated by semantic analyzer.
92 AstNode *fn_def_node;
8393};
8494
8595struct AstNodeFnDef {
......@@ -369,6 +379,7 @@ struct AstNode {
369379 enum NodeType type;
370380 int line;
371381 int column;
382 uint32_t create_index; // for determinism purposes
372383 CodeGenNode *codegen_node;
373384 ImportTableEntry *owner;
374385 union {
test/run_tests.cpp+1-1
......@@ -1203,7 +1203,7 @@ struct A { a : A, }
12031203struct A { b : B, }
12041204struct B { c : C, }
12051205struct C { a : A, }
1206 )SOURCE", 1, ".tmp_source.zig:2:1: error: struct has infinite size");
1206 )SOURCE", 1, ".tmp_source.zig:4:1: error: struct has infinite size");
12071207
12081208 add_compile_fail_case("invalid struct field", R"SOURCE(
12091209struct A { x : i32, }