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,...@@ -14,6 +14,9 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
14 TypeTableEntry *expected_type, AstNode *node);14 TypeTableEntry *expected_type, AstNode *node);
15static TypeTableEntry *eval_const_expr(CodeGen *g, BlockContext *context,15static TypeTableEntry *eval_const_expr(CodeGen *g, BlockContext *context,
16 AstNode *node, AstNodeNumberLiteral *out_number_literal);16 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
18static AstNode *first_executing_node(AstNode *node) {21static 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}
718724
719static void preview_fn_def(CodeGen *g, ImportTableEntry *import, AstNode *node, TypeTableEntry *struct_type) {725static 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;
724739
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;
760767
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);
769788
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 }
772792
773 fn_table->put(proto_name, fn_table_entry);793 fn_table->put(proto_name, fn_table_entry);
774794
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 }
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);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;
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);
789 }809 }
790}810}
791811
792static void preview_function_declarations(CodeGen *g, ImportTableEntry *import, AstNode *node) {812static 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,
881877
882 resolve_struct_type(g, import, type_entry);878 resolve_struct_type(g, import, type_entry);
883879
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
934static 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);
940887 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,
2552static void analyze_top_level_fn_def(CodeGen *g, ImportTableEntry *import, AstNode *node) {2475static void analyze_top_level_fn_def(CodeGen *g, ImportTableEntry *import, AstNode *node) {
2553 assert(node->type == NodeTypeFnDef);2476 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) {
2556 // we detected an error with this function definition which prevents us2482 // 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 }
25602486
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}
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) {
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
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;
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}
27813020
2782static void find_function_declarations_root(CodeGen *g, ImportTableEntry *import, AstNode *node) {3021static 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;
27843027
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 }
27893047
3048 resolve_top_level_decl(g, import, node);
3049 g->unresolved_top_level_decls.remove(node->codegen_node->decl_node.name);
2790}3050}
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) {
2793 assert(node->type == NodeTypeRoot);3053 assert(node->type == NodeTypeRoot);
27943054
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 }
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 }
2800}3084}
28013085
2802static void analyze_top_level_decls_root(CodeGen *g, ImportTableEntry *import, AstNode *node) {3086static 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
28043088
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}
28103094
...@@ -2817,21 +3101,9 @@ void semantic_analyze(CodeGen *g) {...@@ -2817,21 +3101,9 @@ void semantic_analyze(CodeGen *g) {
2817 break;3101 break;
28183102
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 }
28463118
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) {
2857void alloc_codegen_node(AstNode *node) {3128void 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}
28613133
src/analyze.hpp+15-1
...@@ -178,6 +178,10 @@ struct CodeGen {...@@ -178,6 +178,10 @@ struct CodeGen {
178 HashMap<Buf *, bool, buf_hash, buf_eql_buf> link_table;178 HashMap<Buf *, bool, buf_hash, buf_eql_buf> link_table;
179 HashMap<Buf *, ImportTableEntry *, buf_hash, buf_eql_buf> import_table;179 HashMap<Buf *, ImportTableEntry *, buf_hash, buf_eql_buf> import_table;
180 HashMap<Buf *, BuiltinFnEntry *, buf_hash, buf_eql_buf> builtin_fn_table;180 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
182 struct {186 struct {
183 TypeTableEntry *entry_bool;187 TypeTableEntry *entry_bool;
...@@ -270,12 +274,12 @@ struct TypeNode {...@@ -270,12 +274,12 @@ struct TypeNode {
270274
271struct FnProtoNode {275struct FnProtoNode {
272 FnTableEntry *fn_table_entry;276 FnTableEntry *fn_table_entry;
277 bool skip;
273};278};
274279
275struct FnDefNode {280struct FnDefNode {
276 TypeTableEntry *implicit_return_type;281 TypeTableEntry *implicit_return_type;
277 BlockContext *block_context;282 BlockContext *block_context;
278 bool skip;
279};283};
280284
281285
...@@ -364,6 +368,15 @@ struct FnCallNode {...@@ -364,6 +368,15 @@ struct FnCallNode {
364 BuiltinFnEntry *builtin_fn;368 BuiltinFnEntry *builtin_fn;
365};369};
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
367struct CodeGenNode {380struct CodeGenNode {
368 union {381 union {
369 TypeNode type_node; // for NodeTypeType382 TypeNode type_node; // for NodeTypeType
...@@ -388,6 +401,7 @@ struct CodeGenNode {...@@ -388,6 +401,7 @@ struct CodeGenNode {
388 FnCallNode fn_call_node; // for NodeTypeFnCallExpr401 FnCallNode fn_call_node; // for NodeTypeFnCallExpr
389 } data;402 } data;
390 ExprNode expr_node; // for all the expression nodes403 ExprNode expr_node; // for all the expression nodes
404 DeclNode decl_node; // for all top level decls
391};405};
392406
393void semantic_analyze(CodeGen *g);407void semantic_analyze(CodeGen *g);
src/codegen.cpp+17-15
...@@ -23,6 +23,8 @@ CodeGen *codegen_create(Buf *root_source_dir) {...@@ -23,6 +23,8 @@ CodeGen *codegen_create(Buf *root_source_dir) {
23 g->link_table.init(32);23 g->link_table.init(32);
24 g->import_table.init(32);24 g->import_table.init(32);
25 g->builtin_fn_table.init(32);25 g->builtin_fn_table.init(32);
26 g->primitive_type_table.init(32);
27 g->unresolved_top_level_decls.init(32);
26 g->build_type = CodeGenBuildTypeDebug;28 g->build_type = CodeGenBuildTypeDebug;
27 g->root_source_dir = root_source_dir;29 g->root_source_dir = root_source_dir;
2830
...@@ -2109,6 +2111,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -2109,6 +2111,7 @@ static void define_builtin_types(CodeGen *g) {
2109 entry->size_in_bits, entry->align_in_bits,2111 entry->size_in_bits, entry->align_in_bits,
2110 LLVMZigEncoding_DW_ATE_unsigned());2112 LLVMZigEncoding_DW_ATE_unsigned());
2111 g->builtin_types.entry_bool = entry;2113 g->builtin_types.entry_bool = entry;
2114 g->primitive_type_table.put(&entry->name, entry);
2112 }2115 }
2113 {2116 {
2114 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);2117 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
...@@ -2120,6 +2123,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -2120,6 +2123,7 @@ static void define_builtin_types(CodeGen *g) {
2120 entry->size_in_bits, entry->align_in_bits,2123 entry->size_in_bits, entry->align_in_bits,
2121 LLVMZigEncoding_DW_ATE_unsigned());2124 LLVMZigEncoding_DW_ATE_unsigned());
2122 g->builtin_types.entry_u8 = entry;2125 g->builtin_types.entry_u8 = entry;
2126 g->primitive_type_table.put(&entry->name, entry);
2123 }2127 }
2124 {2128 {
2125 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);2129 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
...@@ -2132,6 +2136,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -2132,6 +2136,7 @@ static void define_builtin_types(CodeGen *g) {
2132 entry->size_in_bits, entry->align_in_bits,2136 entry->size_in_bits, entry->align_in_bits,
2133 LLVMZigEncoding_DW_ATE_unsigned());2137 LLVMZigEncoding_DW_ATE_unsigned());
2134 g->builtin_types.entry_u16 = entry;2138 g->builtin_types.entry_u16 = entry;
2139 g->primitive_type_table.put(&entry->name, entry);
2135 }2140 }
2136 {2141 {
2137 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);2142 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
...@@ -2144,6 +2149,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -2144,6 +2149,7 @@ static void define_builtin_types(CodeGen *g) {
2144 entry->size_in_bits, entry->align_in_bits,2149 entry->size_in_bits, entry->align_in_bits,
2145 LLVMZigEncoding_DW_ATE_unsigned());2150 LLVMZigEncoding_DW_ATE_unsigned());
2146 g->builtin_types.entry_u32 = entry;2151 g->builtin_types.entry_u32 = entry;
2152 g->primitive_type_table.put(&entry->name, entry);
2147 }2153 }
2148 {2154 {
2149 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);2155 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
...@@ -2156,6 +2162,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -2156,6 +2162,7 @@ static void define_builtin_types(CodeGen *g) {
2156 entry->size_in_bits, entry->align_in_bits,2162 entry->size_in_bits, entry->align_in_bits,
2157 LLVMZigEncoding_DW_ATE_unsigned());2163 LLVMZigEncoding_DW_ATE_unsigned());
2158 g->builtin_types.entry_u64 = entry;2164 g->builtin_types.entry_u64 = entry;
2165 g->primitive_type_table.put(&entry->name, entry);
2159 }2166 }
2160 g->builtin_types.entry_c_string_literal = get_pointer_to_type(g, g->builtin_types.entry_u8, true, false);2167 g->builtin_types.entry_c_string_literal = get_pointer_to_type(g, g->builtin_types.entry_u8, true, false);
2161 {2168 {
...@@ -2169,6 +2176,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -2169,6 +2176,7 @@ static void define_builtin_types(CodeGen *g) {
2169 entry->size_in_bits, entry->align_in_bits,2176 entry->size_in_bits, entry->align_in_bits,
2170 LLVMZigEncoding_DW_ATE_signed());2177 LLVMZigEncoding_DW_ATE_signed());
2171 g->builtin_types.entry_i8 = entry;2178 g->builtin_types.entry_i8 = entry;
2179 g->primitive_type_table.put(&entry->name, entry);
2172 }2180 }
2173 {2181 {
2174 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);2182 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
...@@ -2181,6 +2189,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -2181,6 +2189,7 @@ static void define_builtin_types(CodeGen *g) {
2181 entry->size_in_bits, entry->align_in_bits,2189 entry->size_in_bits, entry->align_in_bits,
2182 LLVMZigEncoding_DW_ATE_signed());2190 LLVMZigEncoding_DW_ATE_signed());
2183 g->builtin_types.entry_i16 = entry;2191 g->builtin_types.entry_i16 = entry;
2192 g->primitive_type_table.put(&entry->name, entry);
2184 }2193 }
2185 {2194 {
2186 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);2195 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
...@@ -2193,6 +2202,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -2193,6 +2202,7 @@ static void define_builtin_types(CodeGen *g) {
2193 entry->size_in_bits, entry->align_in_bits,2202 entry->size_in_bits, entry->align_in_bits,
2194 LLVMZigEncoding_DW_ATE_signed());2203 LLVMZigEncoding_DW_ATE_signed());
2195 g->builtin_types.entry_i32 = entry;2204 g->builtin_types.entry_i32 = entry;
2205 g->primitive_type_table.put(&entry->name, entry);
2196 }2206 }
2197 {2207 {
2198 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);2208 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
...@@ -2205,6 +2215,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -2205,6 +2215,7 @@ static void define_builtin_types(CodeGen *g) {
2205 entry->size_in_bits, entry->align_in_bits,2215 entry->size_in_bits, entry->align_in_bits,
2206 LLVMZigEncoding_DW_ATE_signed());2216 LLVMZigEncoding_DW_ATE_signed());
2207 g->builtin_types.entry_i64 = entry;2217 g->builtin_types.entry_i64 = entry;
2218 g->primitive_type_table.put(&entry->name, entry);
2208 }2219 }
2209 {2220 {
2210 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);2221 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
...@@ -2217,6 +2228,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -2217,6 +2228,7 @@ static void define_builtin_types(CodeGen *g) {
2217 entry->size_in_bits, entry->align_in_bits,2228 entry->size_in_bits, entry->align_in_bits,
2218 LLVMZigEncoding_DW_ATE_signed());2229 LLVMZigEncoding_DW_ATE_signed());
2219 g->builtin_types.entry_isize = entry;2230 g->builtin_types.entry_isize = entry;
2231 g->primitive_type_table.put(&entry->name, entry);
2220 }2232 }
2221 {2233 {
2222 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);2234 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
...@@ -2229,6 +2241,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -2229,6 +2241,7 @@ static void define_builtin_types(CodeGen *g) {
2229 entry->size_in_bits, entry->align_in_bits,2241 entry->size_in_bits, entry->align_in_bits,
2230 LLVMZigEncoding_DW_ATE_unsigned());2242 LLVMZigEncoding_DW_ATE_unsigned());
2231 g->builtin_types.entry_usize = entry;2243 g->builtin_types.entry_usize = entry;
2244 g->primitive_type_table.put(&entry->name, entry);
2232 }2245 }
2233 {2246 {
2234 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);2247 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);
...@@ -2240,6 +2253,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -2240,6 +2253,7 @@ static void define_builtin_types(CodeGen *g) {
2240 entry->size_in_bits, entry->align_in_bits,2253 entry->size_in_bits, entry->align_in_bits,
2241 LLVMZigEncoding_DW_ATE_float());2254 LLVMZigEncoding_DW_ATE_float());
2242 g->builtin_types.entry_f32 = entry;2255 g->builtin_types.entry_f32 = entry;
2256 g->primitive_type_table.put(&entry->name, entry);
2243 }2257 }
2244 {2258 {
2245 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);2259 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);
...@@ -2251,6 +2265,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -2251,6 +2265,7 @@ static void define_builtin_types(CodeGen *g) {
2251 entry->size_in_bits, entry->align_in_bits,2265 entry->size_in_bits, entry->align_in_bits,
2252 LLVMZigEncoding_DW_ATE_float());2266 LLVMZigEncoding_DW_ATE_float());
2253 g->builtin_types.entry_f64 = entry;2267 g->builtin_types.entry_f64 = entry;
2268 g->primitive_type_table.put(&entry->name, entry);
2254 }2269 }
2255 {2270 {
2256 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdVoid);2271 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdVoid);
...@@ -2260,6 +2275,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -2260,6 +2275,7 @@ static void define_builtin_types(CodeGen *g) {
2260 entry->size_in_bits, entry->align_in_bits,2275 entry->size_in_bits, entry->align_in_bits,
2261 LLVMZigEncoding_DW_ATE_unsigned());2276 LLVMZigEncoding_DW_ATE_unsigned());
2262 g->builtin_types.entry_void = entry;2277 g->builtin_types.entry_void = entry;
2278 g->primitive_type_table.put(&entry->name, entry);
2263 }2279 }
2264 {2280 {
2265 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdUnreachable);2281 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdUnreachable);
...@@ -2267,6 +2283,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -2267,6 +2283,7 @@ static void define_builtin_types(CodeGen *g) {
2267 buf_init_from_str(&entry->name, "unreachable");2283 buf_init_from_str(&entry->name, "unreachable");
2268 entry->di_type = g->builtin_types.entry_void->di_type;2284 entry->di_type = g->builtin_types.entry_void->di_type;
2269 g->builtin_types.entry_unreachable = entry;2285 g->builtin_types.entry_unreachable = entry;
2286 g->primitive_type_table.put(&entry->name, entry);
2270 }2287 }
2271}2288}
22722289
...@@ -2506,21 +2523,6 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *abs_full_path,...@@ -2506,21 +2523,6 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *abs_full_path,
2506 import_entry->path = full_path;2523 import_entry->path = full_path;
2507 import_entry->fn_table.init(32);2524 import_entry->fn_table.init(32);
2508 import_entry->type_table.init(32);2525 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
2525 import_entry->root = ast_parse(source_code, tokenization.tokens, import_entry, g->err_color);2527 import_entry->root = ast_parse(source_code, tokenization.tokens, import_entry, g->err_color);
2526 assert(import_entry->root);2528 assert(import_entry->root);
src/parser.cpp+3
...@@ -457,6 +457,7 @@ struct ParseContext {...@@ -457,6 +457,7 @@ struct ParseContext {
457 ZigList<AstNode *> *directive_list;457 ZigList<AstNode *> *directive_list;
458 ImportTableEntry *owner;458 ImportTableEntry *owner;
459 ErrColor err_color;459 ErrColor err_color;
460 uint32_t next_create_index;
460};461};
461462
462__attribute__ ((format (printf, 4, 5)))463__attribute__ ((format (printf, 4, 5)))
...@@ -512,6 +513,8 @@ static AstNode *ast_create_node_no_line_info(ParseContext *pc, NodeType type) {...@@ -512,6 +513,8 @@ static AstNode *ast_create_node_no_line_info(ParseContext *pc, NodeType type) {
512 AstNode *node = allocate<AstNode>(1);513 AstNode *node = allocate<AstNode>(1);
513 node->type = type;514 node->type = type;
514 node->owner = pc->owner;515 node->owner = pc->owner;
516 node->create_index = pc->next_create_index;
517 pc->next_create_index += 1;
515 return node;518 return node;
516}519}
517520
src/parser.hpp+11
...@@ -80,6 +80,16 @@ struct AstNodeFnProto {...@@ -80,6 +80,16 @@ struct AstNodeFnProto {
80 ZigList<AstNode *> params;80 ZigList<AstNode *> params;
81 AstNode *return_type;81 AstNode *return_type;
82 bool is_var_args;82 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;
83};93};
8494
85struct AstNodeFnDef {95struct AstNodeFnDef {
...@@ -369,6 +379,7 @@ struct AstNode {...@@ -369,6 +379,7 @@ struct AstNode {
369 enum NodeType type;379 enum NodeType type;
370 int line;380 int line;
371 int column;381 int column;
382 uint32_t create_index; // for determinism purposes
372 CodeGenNode *codegen_node;383 CodeGenNode *codegen_node;
373 ImportTableEntry *owner;384 ImportTableEntry *owner;
374 union {385 union {
test/run_tests.cpp+1-1
...@@ -1203,7 +1203,7 @@ struct A { a : A, }...@@ -1203,7 +1203,7 @@ struct A { a : A, }
1203struct A { b : B, }1203struct A { b : B, }
1204struct B { c : C, }1204struct B { c : C, }
1205struct C { a : A, }1205struct 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
1208 add_compile_fail_case("invalid struct field", R"SOURCE(1208 add_compile_fail_case("invalid struct field", R"SOURCE(
1209struct A { x : i32, }1209struct A { x : i32, }