| ... | @@ -9563,7 +9563,11 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, ZigType *type_e | ... | @@ -9563,7 +9563,11 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, ZigType *type_e |
| 9563 | case ZigTypeIdVoid: | 9563 | case ZigTypeIdVoid: |
| 9564 | case ZigTypeIdUnreachable: | 9564 | case ZigTypeIdUnreachable: |
| 9565 | case ZigTypeIdBool: | 9565 | case ZigTypeIdBool: |
| | 9566 | g->c_want_stdbool = true; |
| | 9567 | return; |
| 9566 | case ZigTypeIdInt: | 9568 | case ZigTypeIdInt: |
| | 9569 | g->c_want_stdint = true; |
| | 9570 | return; |
| 9567 | case ZigTypeIdFloat: | 9571 | case ZigTypeIdFloat: |
| 9568 | return; | 9572 | return; |
| 9569 | case ZigTypeIdOpaque: | 9573 | case ZigTypeIdOpaque: |
| ... | @@ -9644,7 +9648,6 @@ static void get_c_type(CodeGen *g, GenH *gen_h, ZigType *type_entry, Buf *out_bu | ... | @@ -9644,7 +9648,6 @@ static void get_c_type(CodeGen *g, GenH *gen_h, ZigType *type_entry, Buf *out_bu |
| 9644 | break; | 9648 | break; |
| 9645 | case ZigTypeIdBool: | 9649 | case ZigTypeIdBool: |
| 9646 | buf_init_from_str(out_buf, "bool"); | 9650 | buf_init_from_str(out_buf, "bool"); |
| 9647 | g->c_want_stdbool = true; | | |
| 9648 | break; | 9651 | break; |
| 9649 | case ZigTypeIdUnreachable: | 9652 | case ZigTypeIdUnreachable: |
| 9650 | buf_init_from_str(out_buf, "__attribute__((__noreturn__)) void"); | 9653 | buf_init_from_str(out_buf, "__attribute__((__noreturn__)) void"); |
| ... | @@ -9668,7 +9671,6 @@ static void get_c_type(CodeGen *g, GenH *gen_h, ZigType *type_entry, Buf *out_bu | ... | @@ -9668,7 +9671,6 @@ static void get_c_type(CodeGen *g, GenH *gen_h, ZigType *type_entry, Buf *out_bu |
| 9668 | } | 9671 | } |
| 9669 | break; | 9672 | break; |
| 9670 | case ZigTypeIdInt: | 9673 | case ZigTypeIdInt: |
| 9671 | g->c_want_stdint = true; | | |
| 9672 | buf_resize(out_buf, 0); | 9674 | buf_resize(out_buf, 0); |
| 9673 | buf_appendf(out_buf, "%sint%" PRIu32 "_t", | 9675 | buf_appendf(out_buf, "%sint%" PRIu32 "_t", |
| 9674 | type_entry->data.integral.is_signed ? "" : "u", | 9676 | type_entry->data.integral.is_signed ? "" : "u", |
| ... | @@ -9780,113 +9782,7 @@ static Buf *preprocessor_mangle(Buf *src) { | ... | @@ -9780,113 +9782,7 @@ static Buf *preprocessor_mangle(Buf *src) { |
| 9780 | return result; | 9782 | return result; |
| 9781 | } | 9783 | } |
| 9782 | | 9784 | |
| 9783 | static void gen_h_file(CodeGen *g) { | 9785 | static void gen_h_file_types(CodeGen* g, GenH* gen_h, Buf* out_buf) { |
| 9784 | GenH gen_h_data = {0}; | | |
| 9785 | GenH *gen_h = &gen_h_data; | | |
| 9786 | | | |
| 9787 | assert(!g->is_test_build); | | |
| 9788 | assert(!g->disable_gen_h); | | |
| 9789 | | | |
| 9790 | Buf *out_h_path = buf_sprintf("%s" OS_SEP "%s.h", buf_ptr(g->output_dir), buf_ptr(g->root_out_name)); | | |
| 9791 | | | |
| 9792 | FILE *out_h = fopen(buf_ptr(out_h_path), "wb"); | | |
| 9793 | if (!out_h) | | |
| 9794 | zig_panic("unable to open %s: %s\n", buf_ptr(out_h_path), strerror(errno)); | | |
| 9795 | | | |
| 9796 | Buf *export_macro = nullptr; | | |
| 9797 | if (g->is_dynamic) { | | |
| 9798 | export_macro = preprocessor_mangle(buf_sprintf("%s_EXPORT", buf_ptr(g->root_out_name))); | | |
| 9799 | buf_upcase(export_macro); | | |
| 9800 | } | | |
| 9801 | | | |
| 9802 | Buf *extern_c_macro = preprocessor_mangle(buf_sprintf("%s_EXTERN_C", buf_ptr(g->root_out_name))); | | |
| 9803 | buf_upcase(extern_c_macro); | | |
| 9804 | | | |
| 9805 | Buf h_buf = BUF_INIT; | | |
| 9806 | buf_resize(&h_buf, 0); | | |
| 9807 | for (size_t fn_def_i = 0; fn_def_i < g->fn_defs.length; fn_def_i += 1) { | | |
| 9808 | ZigFn *fn_table_entry = g->fn_defs.at(fn_def_i); | | |
| 9809 | | | |
| 9810 | if (fn_table_entry->export_list.length == 0) | | |
| 9811 | continue; | | |
| 9812 | | | |
| 9813 | FnTypeId *fn_type_id = &fn_table_entry->type_entry->data.fn.fn_type_id; | | |
| 9814 | | | |
| 9815 | Buf return_type_c = BUF_INIT; | | |
| 9816 | get_c_type(g, gen_h, fn_type_id->return_type, &return_type_c); | | |
| 9817 | | | |
| 9818 | Buf *symbol_name; | | |
| 9819 | if (fn_table_entry->export_list.length == 0) { | | |
| 9820 | symbol_name = &fn_table_entry->symbol_name; | | |
| 9821 | } else { | | |
| 9822 | GlobalExport *fn_export = &fn_table_entry->export_list.items[0]; | | |
| 9823 | symbol_name = &fn_export->name; | | |
| 9824 | } | | |
| 9825 | | | |
| 9826 | buf_appendf(&h_buf, "%s %s %s(", | | |
| 9827 | buf_ptr(g->is_dynamic ? export_macro : extern_c_macro), | | |
| 9828 | buf_ptr(&return_type_c), | | |
| 9829 | buf_ptr(symbol_name)); | | |
| 9830 | | | |
| 9831 | Buf param_type_c = BUF_INIT; | | |
| 9832 | if (fn_type_id->param_count > 0) { | | |
| 9833 | for (size_t param_i = 0; param_i < fn_type_id->param_count; param_i += 1) { | | |
| 9834 | FnTypeParamInfo *param_info = &fn_type_id->param_info[param_i]; | | |
| 9835 | AstNode *param_decl_node = get_param_decl_node(fn_table_entry, param_i); | | |
| 9836 | Buf *param_name = param_decl_node->data.param_decl.name; | | |
| 9837 | | | |
| 9838 | const char *comma_str = (param_i == 0) ? "" : ", "; | | |
| 9839 | const char *restrict_str = param_info->is_noalias ? "restrict" : ""; | | |
| 9840 | get_c_type(g, gen_h, param_info->type, &param_type_c); | | |
| 9841 | | | |
| 9842 | if (param_info->type->id == ZigTypeIdArray) { | | |
| 9843 | // Arrays decay to pointers | | |
| 9844 | buf_appendf(&h_buf, "%s%s%s %s[]", comma_str, buf_ptr(&param_type_c), | | |
| 9845 | restrict_str, buf_ptr(param_name)); | | |
| 9846 | } else { | | |
| 9847 | buf_appendf(&h_buf, "%s%s%s %s", comma_str, buf_ptr(&param_type_c), | | |
| 9848 | restrict_str, buf_ptr(param_name)); | | |
| 9849 | } | | |
| 9850 | } | | |
| 9851 | buf_appendf(&h_buf, ")"); | | |
| 9852 | } else { | | |
| 9853 | buf_appendf(&h_buf, "void)"); | | |
| 9854 | } | | |
| 9855 | | | |
| 9856 | buf_appendf(&h_buf, ";\n"); | | |
| 9857 | | | |
| 9858 | } | | |
| 9859 | | | |
| 9860 | Buf *ifdef_dance_name = preprocessor_mangle(buf_sprintf("%s_H", buf_ptr(g->root_out_name))); | | |
| 9861 | buf_upcase(ifdef_dance_name); | | |
| 9862 | | | |
| 9863 | fprintf(out_h, "#ifndef %s\n", buf_ptr(ifdef_dance_name)); | | |
| 9864 | fprintf(out_h, "#define %s\n\n", buf_ptr(ifdef_dance_name)); | | |
| 9865 | | | |
| 9866 | if (g->c_want_stdbool) | | |
| 9867 | fprintf(out_h, "#include <stdbool.h>\n"); | | |
| 9868 | if (g->c_want_stdint) | | |
| 9869 | fprintf(out_h, "#include <stdint.h>\n"); | | |
| 9870 | | | |
| 9871 | fprintf(out_h, "\n"); | | |
| 9872 | | | |
| 9873 | fprintf(out_h, "#ifdef __cplusplus\n"); | | |
| 9874 | fprintf(out_h, "#define %s extern \"C\"\n", buf_ptr(extern_c_macro)); | | |
| 9875 | fprintf(out_h, "#else\n"); | | |
| 9876 | fprintf(out_h, "#define %s\n", buf_ptr(extern_c_macro)); | | |
| 9877 | fprintf(out_h, "#endif\n"); | | |
| 9878 | fprintf(out_h, "\n"); | | |
| 9879 | | | |
| 9880 | if (g->is_dynamic) { | | |
| 9881 | fprintf(out_h, "#if defined(_WIN32)\n"); | | |
| 9882 | fprintf(out_h, "#define %s %s __declspec(dllimport)\n", buf_ptr(export_macro), buf_ptr(extern_c_macro)); | | |
| 9883 | fprintf(out_h, "#else\n"); | | |
| 9884 | fprintf(out_h, "#define %s %s __attribute__((visibility (\"default\")))\n", | | |
| 9885 | buf_ptr(export_macro), buf_ptr(extern_c_macro)); | | |
| 9886 | fprintf(out_h, "#endif\n"); | | |
| 9887 | fprintf(out_h, "\n"); | | |
| 9888 | } | | |
| 9889 | | | |
| 9890 | for (size_t type_i = 0; type_i < gen_h->types_to_declare.length; type_i += 1) { | 9786 | for (size_t type_i = 0; type_i < gen_h->types_to_declare.length; type_i += 1) { |
| 9891 | ZigType *type_entry = gen_h->types_to_declare.at(type_i); | 9787 | ZigType *type_entry = gen_h->types_to_declare.at(type_i); |
| 9892 | switch (type_entry->id) { | 9788 | switch (type_entry->id) { |
| ... | @@ -9917,25 +9813,25 @@ static void gen_h_file(CodeGen *g) { | ... | @@ -9917,25 +9813,25 @@ static void gen_h_file(CodeGen *g) { |
| 9917 | | 9813 | |
| 9918 | case ZigTypeIdEnum: | 9814 | case ZigTypeIdEnum: |
| 9919 | if (type_entry->data.enumeration.layout == ContainerLayoutExtern) { | 9815 | if (type_entry->data.enumeration.layout == ContainerLayoutExtern) { |
| 9920 | fprintf(out_h, "enum %s {\n", buf_ptr(type_h_name(type_entry))); | 9816 | buf_appendf(out_buf, "enum %s {\n", buf_ptr(type_h_name(type_entry))); |
| 9921 | for (uint32_t field_i = 0; field_i < type_entry->data.enumeration.src_field_count; field_i += 1) { | 9817 | for (uint32_t field_i = 0; field_i < type_entry->data.enumeration.src_field_count; field_i += 1) { |
| 9922 | TypeEnumField *enum_field = &type_entry->data.enumeration.fields[field_i]; | 9818 | TypeEnumField *enum_field = &type_entry->data.enumeration.fields[field_i]; |
| 9923 | Buf *value_buf = buf_alloc(); | 9819 | Buf *value_buf = buf_alloc(); |
| 9924 | bigint_append_buf(value_buf, &enum_field->value, 10); | 9820 | bigint_append_buf(value_buf, &enum_field->value, 10); |
| 9925 | fprintf(out_h, " %s = %s", buf_ptr(enum_field->name), buf_ptr(value_buf)); | 9821 | buf_appendf(out_buf, " %s = %s", buf_ptr(enum_field->name), buf_ptr(value_buf)); |
| 9926 | if (field_i != type_entry->data.enumeration.src_field_count - 1) { | 9822 | if (field_i != type_entry->data.enumeration.src_field_count - 1) { |
| 9927 | fprintf(out_h, ","); | 9823 | buf_appendf(out_buf, ","); |
| 9928 | } | 9824 | } |
| 9929 | fprintf(out_h, "\n"); | 9825 | buf_appendf(out_buf, "\n"); |
| 9930 | } | 9826 | } |
| 9931 | fprintf(out_h, "};\n\n"); | 9827 | buf_appendf(out_buf, "};\n\n"); |
| 9932 | } else { | 9828 | } else { |
| 9933 | fprintf(out_h, "enum %s;\n", buf_ptr(type_h_name(type_entry))); | 9829 | buf_appendf(out_buf, "enum %s;\n\n", buf_ptr(type_h_name(type_entry))); |
| 9934 | } | 9830 | } |
| 9935 | break; | 9831 | break; |
| 9936 | case ZigTypeIdStruct: | 9832 | case ZigTypeIdStruct: |
| 9937 | if (type_entry->data.structure.layout == ContainerLayoutExtern) { | 9833 | if (type_entry->data.structure.layout == ContainerLayoutExtern) { |
| 9938 | fprintf(out_h, "struct %s {\n", buf_ptr(type_h_name(type_entry))); | 9834 | buf_appendf(out_buf, "struct %s {\n", buf_ptr(type_h_name(type_entry))); |
| 9939 | for (uint32_t field_i = 0; field_i < type_entry->data.structure.src_field_count; field_i += 1) { | 9835 | for (uint32_t field_i = 0; field_i < type_entry->data.structure.src_field_count; field_i += 1) { |
| 9940 | TypeStructField *struct_field = type_entry->data.structure.fields[field_i]; | 9836 | TypeStructField *struct_field = type_entry->data.structure.fields[field_i]; |
| 9941 | | 9837 | |
| ... | @@ -9943,43 +9839,194 @@ static void gen_h_file(CodeGen *g) { | ... | @@ -9943,43 +9839,194 @@ static void gen_h_file(CodeGen *g) { |
| 9943 | get_c_type(g, gen_h, struct_field->type_entry, type_name_buf); | 9839 | get_c_type(g, gen_h, struct_field->type_entry, type_name_buf); |
| 9944 | | 9840 | |
| 9945 | if (struct_field->type_entry->id == ZigTypeIdArray) { | 9841 | if (struct_field->type_entry->id == ZigTypeIdArray) { |
| 9946 | fprintf(out_h, " %s %s[%" ZIG_PRI_u64 "];\n", buf_ptr(type_name_buf), | 9842 | buf_appendf(out_buf, " %s %s[%" ZIG_PRI_u64 "];\n", buf_ptr(type_name_buf), |
| 9947 | buf_ptr(struct_field->name), | 9843 | buf_ptr(struct_field->name), |
| 9948 | struct_field->type_entry->data.array.len); | 9844 | struct_field->type_entry->data.array.len); |
| 9949 | } else { | 9845 | } else { |
| 9950 | fprintf(out_h, " %s %s;\n", buf_ptr(type_name_buf), buf_ptr(struct_field->name)); | 9846 | buf_appendf(out_buf, " %s %s;\n", buf_ptr(type_name_buf), buf_ptr(struct_field->name)); |
| 9951 | } | 9847 | } |
| 9952 | | 9848 | |
| 9953 | } | 9849 | } |
| 9954 | fprintf(out_h, "};\n\n"); | 9850 | buf_appendf(out_buf, "};\n\n"); |
| 9955 | } else { | 9851 | } else { |
| 9956 | fprintf(out_h, "struct %s;\n", buf_ptr(type_h_name(type_entry))); | 9852 | buf_appendf(out_buf, "struct %s;\n\n", buf_ptr(type_h_name(type_entry))); |
| 9957 | } | 9853 | } |
| 9958 | break; | 9854 | break; |
| 9959 | case ZigTypeIdUnion: | 9855 | case ZigTypeIdUnion: |
| 9960 | if (type_entry->data.unionation.layout == ContainerLayoutExtern) { | 9856 | if (type_entry->data.unionation.layout == ContainerLayoutExtern) { |
| 9961 | fprintf(out_h, "union %s {\n", buf_ptr(type_h_name(type_entry))); | 9857 | buf_appendf(out_buf, "union %s {\n", buf_ptr(type_h_name(type_entry))); |
| 9962 | for (uint32_t field_i = 0; field_i < type_entry->data.unionation.src_field_count; field_i += 1) { | 9858 | for (uint32_t field_i = 0; field_i < type_entry->data.unionation.src_field_count; field_i += 1) { |
| 9963 | TypeUnionField *union_field = &type_entry->data.unionation.fields[field_i]; | 9859 | TypeUnionField *union_field = &type_entry->data.unionation.fields[field_i]; |
| 9964 | | 9860 | |
| 9965 | Buf *type_name_buf = buf_alloc(); | 9861 | Buf *type_name_buf = buf_alloc(); |
| 9966 | get_c_type(g, gen_h, union_field->type_entry, type_name_buf); | 9862 | get_c_type(g, gen_h, union_field->type_entry, type_name_buf); |
| 9967 | fprintf(out_h, " %s %s;\n", buf_ptr(type_name_buf), buf_ptr(union_field->name)); | 9863 | buf_appendf(out_buf, " %s %s;\n", buf_ptr(type_name_buf), buf_ptr(union_field->name)); |
| 9968 | } | 9864 | } |
| 9969 | fprintf(out_h, "};\n\n"); | 9865 | buf_appendf(out_buf, "};\n\n"); |
| 9970 | } else { | 9866 | } else { |
| 9971 | fprintf(out_h, "union %s;\n", buf_ptr(type_h_name(type_entry))); | 9867 | buf_appendf(out_buf, "union %s;\n\n", buf_ptr(type_h_name(type_entry))); |
| 9972 | } | 9868 | } |
| 9973 | break; | 9869 | break; |
| 9974 | case ZigTypeIdOpaque: | 9870 | case ZigTypeIdOpaque: |
| 9975 | fprintf(out_h, "struct %s;\n\n", buf_ptr(type_h_name(type_entry))); | 9871 | buf_appendf(out_buf, "struct %s;\n\n", buf_ptr(type_h_name(type_entry))); |
| 9976 | break; | 9872 | break; |
| 9977 | } | 9873 | } |
| 9978 | } | 9874 | } |
| | 9875 | } |
| | 9876 | |
| | 9877 | static void gen_h_file_functions(CodeGen* g, GenH* gen_h, Buf* out_buf, Buf* export_macro) { |
| | 9878 | for (size_t fn_def_i = 0; fn_def_i < g->fn_defs.length; fn_def_i += 1) { |
| | 9879 | ZigFn *fn_table_entry = g->fn_defs.at(fn_def_i); |
| | 9880 | |
| | 9881 | if (fn_table_entry->export_list.length == 0) |
| | 9882 | continue; |
| | 9883 | |
| | 9884 | FnTypeId *fn_type_id = &fn_table_entry->type_entry->data.fn.fn_type_id; |
| | 9885 | |
| | 9886 | Buf return_type_c = BUF_INIT; |
| | 9887 | get_c_type(g, gen_h, fn_type_id->return_type, &return_type_c); |
| | 9888 | |
| | 9889 | Buf *symbol_name; |
| | 9890 | if (fn_table_entry->export_list.length == 0) { |
| | 9891 | symbol_name = &fn_table_entry->symbol_name; |
| | 9892 | } else { |
| | 9893 | GlobalExport *fn_export = &fn_table_entry->export_list.items[0]; |
| | 9894 | symbol_name = &fn_export->name; |
| | 9895 | } |
| | 9896 | |
| | 9897 | if (export_macro != nullptr) { |
| | 9898 | buf_appendf(out_buf, "%s %s %s(", |
| | 9899 | buf_ptr(export_macro), |
| | 9900 | buf_ptr(&return_type_c), |
| | 9901 | buf_ptr(symbol_name)); |
| | 9902 | } else { |
| | 9903 | buf_appendf(out_buf, "%s %s(", |
| | 9904 | buf_ptr(&return_type_c), |
| | 9905 | buf_ptr(symbol_name)); |
| | 9906 | } |
| | 9907 | |
| | 9908 | Buf param_type_c = BUF_INIT; |
| | 9909 | if (fn_type_id->param_count > 0) { |
| | 9910 | for (size_t param_i = 0; param_i < fn_type_id->param_count; param_i += 1) { |
| | 9911 | FnTypeParamInfo *param_info = &fn_type_id->param_info[param_i]; |
| | 9912 | AstNode *param_decl_node = get_param_decl_node(fn_table_entry, param_i); |
| | 9913 | Buf *param_name = param_decl_node->data.param_decl.name; |
| | 9914 | |
| | 9915 | const char *comma_str = (param_i == 0) ? "" : ", "; |
| | 9916 | const char *restrict_str = param_info->is_noalias ? "restrict" : ""; |
| | 9917 | get_c_type(g, gen_h, param_info->type, &param_type_c); |
| | 9918 | |
| | 9919 | if (param_info->type->id == ZigTypeIdArray) { |
| | 9920 | // Arrays decay to pointers |
| | 9921 | buf_appendf(out_buf, "%s%s%s %s[]", comma_str, buf_ptr(&param_type_c), |
| | 9922 | restrict_str, buf_ptr(param_name)); |
| | 9923 | } else { |
| | 9924 | buf_appendf(out_buf, "%s%s%s %s", comma_str, buf_ptr(&param_type_c), |
| | 9925 | restrict_str, buf_ptr(param_name)); |
| | 9926 | } |
| | 9927 | } |
| | 9928 | buf_appendf(out_buf, ")"); |
| | 9929 | } else { |
| | 9930 | buf_appendf(out_buf, "void)"); |
| | 9931 | } |
| | 9932 | |
| | 9933 | buf_appendf(out_buf, ";\n"); |
| | 9934 | } |
| | 9935 | } |
| | 9936 | |
| | 9937 | static void gen_h_file_variables(CodeGen* g, GenH* gen_h, Buf* h_buf, Buf* export_macro) { |
| | 9938 | for (size_t exp_var_i = 0; exp_var_i < g->global_vars.length; exp_var_i += 1) { |
| | 9939 | ZigVar* var = g->global_vars.at(exp_var_i)->var; |
| | 9940 | if (var->export_list.length == 0) |
| | 9941 | continue; |
| | 9942 | |
| | 9943 | Buf var_type_c = BUF_INIT; |
| | 9944 | get_c_type(g, gen_h, var->var_type, &var_type_c); |
| | 9945 | |
| | 9946 | if (export_macro != nullptr) { |
| | 9947 | buf_appendf(h_buf, "extern %s %s %s;\n", |
| | 9948 | buf_ptr(export_macro), |
| | 9949 | buf_ptr(&var_type_c), |
| | 9950 | var->name); |
| | 9951 | } else { |
| | 9952 | buf_appendf(h_buf, "extern %s %s;\n", |
| | 9953 | buf_ptr(&var_type_c), |
| | 9954 | var->name); |
| | 9955 | } |
| | 9956 | } |
| | 9957 | } |
| | 9958 | |
| | 9959 | static void gen_h_file(CodeGen *g) { |
| | 9960 | GenH gen_h_data = {0}; |
| | 9961 | GenH *gen_h = &gen_h_data; |
| | 9962 | |
| | 9963 | assert(!g->is_test_build); |
| | 9964 | assert(!g->disable_gen_h); |
| | 9965 | |
| | 9966 | Buf *out_h_path = buf_sprintf("%s" OS_SEP "%s.h", buf_ptr(g->output_dir), buf_ptr(g->root_out_name)); |
| | 9967 | |
| | 9968 | FILE *out_h = fopen(buf_ptr(out_h_path), "wb"); |
| | 9969 | if (!out_h) |
| | 9970 | zig_panic("unable to open %s: %s\n", buf_ptr(out_h_path), strerror(errno)); |
| | 9971 | |
| | 9972 | Buf *export_macro = nullptr; |
| | 9973 | if (g->is_dynamic) { |
| | 9974 | export_macro = preprocessor_mangle(buf_sprintf("%s_EXPORT", buf_ptr(g->root_out_name))); |
| | 9975 | buf_upcase(export_macro); |
| | 9976 | } |
| | 9977 | |
| | 9978 | Buf fns_buf = BUF_INIT; |
| | 9979 | buf_resize(&fns_buf, 0); |
| | 9980 | gen_h_file_functions(g, gen_h, &fns_buf, export_macro); |
| | 9981 | |
| | 9982 | Buf vars_buf = BUF_INIT; |
| | 9983 | buf_resize(&vars_buf, 0); |
| | 9984 | gen_h_file_variables(g, gen_h, &vars_buf, export_macro); |
| | 9985 | |
| | 9986 | // Types will be populated by exported functions and variables so it has to run last. |
| | 9987 | Buf types_buf = BUF_INIT; |
| | 9988 | buf_resize(&types_buf, 0); |
| | 9989 | gen_h_file_types(g, gen_h, &types_buf); |
| | 9990 | |
| | 9991 | Buf *ifdef_dance_name = preprocessor_mangle(buf_sprintf("%s_H", buf_ptr(g->root_out_name))); |
| | 9992 | buf_upcase(ifdef_dance_name); |
| | 9993 | |
| | 9994 | fprintf(out_h, "#ifndef %s\n", buf_ptr(ifdef_dance_name)); |
| | 9995 | fprintf(out_h, "#define %s\n\n", buf_ptr(ifdef_dance_name)); |
| | 9996 | |
| | 9997 | if (g->c_want_stdbool) |
| | 9998 | fprintf(out_h, "#include <stdbool.h>\n"); |
| | 9999 | if (g->c_want_stdint) |
| | 10000 | fprintf(out_h, "#include <stdint.h>\n"); |
| | 10001 | |
| | 10002 | fprintf(out_h, "\n"); |
| | 10003 | |
| | 10004 | if (g->is_dynamic) { |
| | 10005 | fprintf(out_h, "#if defined(_WIN32)\n"); |
| | 10006 | fprintf(out_h, "#define %s __declspec(dllimport)\n", buf_ptr(export_macro)); |
| | 10007 | fprintf(out_h, "#else\n"); |
| | 10008 | fprintf(out_h, "#define %s __attribute__((visibility (\"default\")))\n", |
| | 10009 | buf_ptr(export_macro)); |
| | 10010 | fprintf(out_h, "#endif\n"); |
| | 10011 | fprintf(out_h, "\n"); |
| | 10012 | } |
| | 10013 | |
| | 10014 | fprintf(out_h, "%s", buf_ptr(&types_buf)); |
| | 10015 | |
| | 10016 | fprintf(out_h, "#ifdef __cplusplus\n"); |
| | 10017 | fprintf(out_h, "extern \"C\" {\n"); |
| | 10018 | fprintf(out_h, "#endif\n"); |
| | 10019 | fprintf(out_h, "\n"); |
| | 10020 | |
| | 10021 | fprintf(out_h, "%s\n", buf_ptr(&fns_buf)); |
| | 10022 | |
| | 10023 | fprintf(out_h, "#ifdef __cplusplus\n"); |
| | 10024 | fprintf(out_h, "} // extern \"C\"\n"); |
| | 10025 | fprintf(out_h, "#endif\n\n"); |
| 9979 | | 10026 | |
| 9980 | fprintf(out_h, "%s", buf_ptr(&h_buf)); | 10027 | fprintf(out_h, "%s\n", buf_ptr(&vars_buf)); |
| 9981 | | 10028 | |
| 9982 | fprintf(out_h, "\n#endif\n"); | 10029 | fprintf(out_h, "#endif // %s\n", buf_ptr(ifdef_dance_name)); |
| 9983 | | 10030 | |
| 9984 | if (fclose(out_h)) | 10031 | if (fclose(out_h)) |
| 9985 | zig_panic("unable to close h file: %s", strerror(errno)); | 10032 | zig_panic("unable to close h file: %s", strerror(errno)); |