authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-30 00:25:52-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2019-11-30 00:25:52-05:00
log85e1e3b95f1f1699a842a5e889d8987692a829a4
tree74eff09f778dafe1b77ea1e1ec764b3ade3b4eb8
parentf980c29306ac9435662bde6fb5557ca0c6d98310
parent6ebd26f3dbaf54230f24118043fe91d1f09f9e8e
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #3284 from Sahnvour/export_variables

Improved support for exporting variables

9 files changed, 217 insertions(+), 150 deletions(-)

src-self-hosted/stage1.zig+3-3
......@@ -427,11 +427,11 @@ export fn stage2_DepTokenizer_next(self: *stage2_DepTokenizer) stage2_DepNextRes
427427 };
428428}
429429
430export const stage2_DepTokenizer = extern struct {
430const stage2_DepTokenizer = extern struct {
431431 handle: *DepTokenizer,
432432};
433433
434export const stage2_DepNextResult = extern struct {
434const stage2_DepNextResult = extern struct {
435435 type_id: TypeId,
436436
437437 // when type_id == error --> error text
......@@ -440,7 +440,7 @@ export const stage2_DepNextResult = extern struct {
440440 // when type_id == prereq --> prereq pathname
441441 textz: [*]const u8,
442442
443 export const TypeId = extern enum {
443 const TypeId = extern enum {
444444 error_,
445445 null_,
446446 target,
src/analyze.cpp+11
......@@ -3792,6 +3792,16 @@ ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf
37923792 return variable_entry;
37933793}
37943794
3795static void validate_export_var_type(CodeGen *g, ZigType* type, AstNode *source_node) {
3796 switch (type->id) {
3797 case ZigTypeIdMetaType:
3798 add_node_error(g, source_node, buf_sprintf("cannot export variable of type 'type'"));
3799 break;
3800 default:
3801 break;
3802 }
3803}
3804
37953805static void resolve_decl_var(CodeGen *g, TldVar *tld_var, bool allow_lazy) {
37963806 AstNode *source_node = tld_var->base.source_node;
37973807 AstNodeVariableDeclaration *var_decl = &source_node->data.variable_declaration;
......@@ -3881,6 +3891,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var, bool allow_lazy) {
38813891 }
38823892
38833893 if (is_export) {
3894 validate_export_var_type(g, type, source_node);
38843895 add_var_export(g, tld_var->var, tld_var->var->name, GlobalLinkageIdStrong);
38853896 }
38863897
src/codegen.cpp+174-127
......@@ -9563,7 +9563,11 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, ZigType *type_e
95639563 case ZigTypeIdVoid:
95649564 case ZigTypeIdUnreachable:
95659565 case ZigTypeIdBool:
9566 g->c_want_stdbool = true;
9567 return;
95669568 case ZigTypeIdInt:
9569 g->c_want_stdint = true;
9570 return;
95679571 case ZigTypeIdFloat:
95689572 return;
95699573 case ZigTypeIdOpaque:
......@@ -9644,7 +9648,6 @@ static void get_c_type(CodeGen *g, GenH *gen_h, ZigType *type_entry, Buf *out_bu
96449648 break;
96459649 case ZigTypeIdBool:
96469650 buf_init_from_str(out_buf, "bool");
9647 g->c_want_stdbool = true;
96489651 break;
96499652 case ZigTypeIdUnreachable:
96509653 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
96689671 }
96699672 break;
96709673 case ZigTypeIdInt:
9671 g->c_want_stdint = true;
96729674 buf_resize(out_buf, 0);
96739675 buf_appendf(out_buf, "%sint%" PRIu32 "_t",
96749676 type_entry->data.integral.is_signed ? "" : "u",
......@@ -9780,113 +9782,7 @@ static Buf *preprocessor_mangle(Buf *src) {
97809782 return result;
97819783}
97829784
9783static void gen_h_file(CodeGen *g) {
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
9785static void gen_h_file_types(CodeGen* g, GenH* gen_h, Buf* out_buf) {
98909786 for (size_t type_i = 0; type_i < gen_h->types_to_declare.length; type_i += 1) {
98919787 ZigType *type_entry = gen_h->types_to_declare.at(type_i);
98929788 switch (type_entry->id) {
......@@ -9917,25 +9813,25 @@ static void gen_h_file(CodeGen *g) {
99179813
99189814 case ZigTypeIdEnum:
99199815 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)));
99219817 for (uint32_t field_i = 0; field_i < type_entry->data.enumeration.src_field_count; field_i += 1) {
99229818 TypeEnumField *enum_field = &type_entry->data.enumeration.fields[field_i];
99239819 Buf *value_buf = buf_alloc();
99249820 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));
99269822 if (field_i != type_entry->data.enumeration.src_field_count - 1) {
9927 fprintf(out_h, ",");
9823 buf_appendf(out_buf, ",");
99289824 }
9929 fprintf(out_h, "\n");
9825 buf_appendf(out_buf, "\n");
99309826 }
9931 fprintf(out_h, "};\n\n");
9827 buf_appendf(out_buf, "};\n\n");
99329828 } 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)));
99349830 }
99359831 break;
99369832 case ZigTypeIdStruct:
99379833 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)));
99399835 for (uint32_t field_i = 0; field_i < type_entry->data.structure.src_field_count; field_i += 1) {
99409836 TypeStructField *struct_field = type_entry->data.structure.fields[field_i];
99419837
......@@ -9943,43 +9839,194 @@ static void gen_h_file(CodeGen *g) {
99439839 get_c_type(g, gen_h, struct_field->type_entry, type_name_buf);
99449840
99459841 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),
99479843 buf_ptr(struct_field->name),
99489844 struct_field->type_entry->data.array.len);
99499845 } 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));
99519847 }
99529848
99539849 }
9954 fprintf(out_h, "};\n\n");
9850 buf_appendf(out_buf, "};\n\n");
99559851 } 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)));
99579853 }
99589854 break;
99599855 case ZigTypeIdUnion:
99609856 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)));
99629858 for (uint32_t field_i = 0; field_i < type_entry->data.unionation.src_field_count; field_i += 1) {
99639859 TypeUnionField *union_field = &type_entry->data.unionation.fields[field_i];
99649860
99659861 Buf *type_name_buf = buf_alloc();
99669862 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));
99689864 }
9969 fprintf(out_h, "};\n\n");
9865 buf_appendf(out_buf, "};\n\n");
99709866 } 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)));
99729868 }
99739869 break;
99749870 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)));
99769872 break;
99779873 }
99789874 }
9875}
9876
9877static 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
9937static 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
9959static 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");
997910026
9980 fprintf(out_h, "%s", buf_ptr(&h_buf));
10027 fprintf(out_h, "%s\n", buf_ptr(&vars_buf));
998110028
9982 fprintf(out_h, "\n#endif\n");
10029 fprintf(out_h, "#endif // %s\n", buf_ptr(ifdef_dance_name));
998310030
998410031 if (fclose(out_h))
998510032 zig_panic("unable to close h file: %s", strerror(errno));
src/libc_installation.cpp+1-1
......@@ -389,7 +389,7 @@ static Error zig_libc_find_native_msvc_include_dir(ZigLibCInstallation *self, Zi
389389 }
390390 Buf search_path = BUF_INIT;
391391 buf_init_from_mem(&search_path, sdk->msvc_lib_dir_ptr, sdk->msvc_lib_dir_len);
392 buf_append_str(&search_path, "\\..\\..\\include");
392 buf_append_str(&search_path, "..\\..\\include");
393393
394394 Buf *vcruntime_path = buf_sprintf("%s\\vcruntime.h", buf_ptr(&search_path));
395395 bool exists;
src/os.cpp+4-4
......@@ -1554,7 +1554,7 @@ void os_stderr_set_color(TermColor color) {
15541554Error os_get_win32_ucrt_lib_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_ArchType platform_type) {
15551555#if defined(ZIG_OS_WINDOWS)
15561556 buf_resize(output_buf, 0);
1557 buf_appendf(output_buf, "%s\\Lib\\%s\\ucrt\\", sdk->path10_ptr, sdk->version10_ptr);
1557 buf_appendf(output_buf, "%sLib\\%s\\ucrt\\", sdk->path10_ptr, sdk->version10_ptr);
15581558 switch (platform_type) {
15591559 case ZigLLVM_x86:
15601560 buf_append_str(output_buf, "x86\\");
......@@ -1586,7 +1586,7 @@ Error os_get_win32_ucrt_lib_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_Ar
15861586Error os_get_win32_ucrt_include_path(ZigWindowsSDK *sdk, Buf* output_buf) {
15871587#if defined(ZIG_OS_WINDOWS)
15881588 buf_resize(output_buf, 0);
1589 buf_appendf(output_buf, "%s\\Include\\%s\\ucrt", sdk->path10_ptr, sdk->version10_ptr);
1589 buf_appendf(output_buf, "%sInclude\\%s\\ucrt", sdk->path10_ptr, sdk->version10_ptr);
15901590 if (GetFileAttributesA(buf_ptr(output_buf)) != INVALID_FILE_ATTRIBUTES) {
15911591 return ErrorNone;
15921592 }
......@@ -1603,7 +1603,7 @@ Error os_get_win32_kern32_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_Arch
16031603#if defined(ZIG_OS_WINDOWS)
16041604 {
16051605 buf_resize(output_buf, 0);
1606 buf_appendf(output_buf, "%s\\Lib\\%s\\um\\", sdk->path10_ptr, sdk->version10_ptr);
1606 buf_appendf(output_buf, "%sLib\\%s\\um\\", sdk->path10_ptr, sdk->version10_ptr);
16071607 switch (platform_type) {
16081608 case ZigLLVM_x86:
16091609 buf_append_str(output_buf, "x86\\");
......@@ -1626,7 +1626,7 @@ Error os_get_win32_kern32_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_Arch
16261626 }
16271627 {
16281628 buf_resize(output_buf, 0);
1629 buf_appendf(output_buf, "%s\\Lib\\%s\\um\\", sdk->path81_ptr, sdk->version81_ptr);
1629 buf_appendf(output_buf, "%sLib\\%s\\um\\", sdk->path81_ptr, sdk->version81_ptr);
16301630 switch (platform_type) {
16311631 case ZigLLVM_x86:
16321632 buf_append_str(output_buf, "x86\\");
test/gen_h.zig+17-15
......@@ -10,9 +10,8 @@ pub fn addCases(cases: *tests.GenHContext) void {
1010 \\ B = 1,
1111 \\ C = 2
1212 \\};
13 \\
14 \\TEST_EXTERN_C void entry(enum Foo foo);
15 \\
13 ,
14 \\void entry(enum Foo foo);
1615 );
1716
1817 cases.add("declare struct",
......@@ -34,8 +33,8 @@ pub fn addCases(cases: *tests.GenHContext) void {
3433 \\ uint64_t E;
3534 \\ uint64_t F;
3635 \\};
37 \\
38 \\TEST_EXTERN_C void entry(struct Foo foo);
36 ,
37 \\void entry(struct Foo foo);
3938 \\
4039 );
4140
......@@ -69,19 +68,19 @@ pub fn addCases(cases: *tests.GenHContext) void {
6968 \\ bool C;
7069 \\ struct Big D;
7170 \\};
72 \\
73 \\TEST_EXTERN_C void entry(union Foo foo);
71 ,
72 \\void entry(union Foo foo);
7473 \\
7574 );
7675
7776 cases.add("declare opaque type",
78 \\export const Foo = @OpaqueType();
77 \\const Foo = @OpaqueType();
7978 \\
8079 \\export fn entry(foo: ?*Foo) void { }
8180 ,
8281 \\struct Foo;
83 \\
84 \\TEST_EXTERN_C void entry(struct Foo * foo);
82 ,
83 \\void entry(struct Foo * foo);
8584 );
8685
8786 cases.add("array field-type",
......@@ -95,8 +94,8 @@ pub fn addCases(cases: *tests.GenHContext) void {
9594 \\ int32_t A[2];
9695 \\ uint32_t * B[4];
9796 \\};
98 \\
99 \\TEST_EXTERN_C void entry(struct Foo foo, uint8_t bar[]);
97 ,
98 \\void entry(struct Foo foo, uint8_t bar[]);
10099 \\
101100 );
102101
......@@ -110,7 +109,8 @@ pub fn addCases(cases: *tests.GenHContext) void {
110109 \\}
111110 ,
112111 \\struct S;
113 \\TEST_EXTERN_C uint8_t a(struct S * s);
112 ,
113 \\uint8_t a(struct S * s);
114114 \\
115115 );
116116
......@@ -125,7 +125,8 @@ pub fn addCases(cases: *tests.GenHContext) void {
125125 \\}
126126 ,
127127 \\union U;
128 \\TEST_EXTERN_C uint8_t a(union U * s);
128 ,
129 \\uint8_t a(union U * s);
129130 \\
130131 );
131132
......@@ -140,7 +141,8 @@ pub fn addCases(cases: *tests.GenHContext) void {
140141 \\}
141142 ,
142143 \\enum E;
143 \\TEST_EXTERN_C uint8_t a(enum E * s);
144 ,
145 \\uint8_t a(enum E * s);
144146 \\
145147 );
146148}
test/standalone/static_c_lib/foo.c+2
......@@ -2,3 +2,5 @@
22uint32_t add(uint32_t a, uint32_t b) {
33 return a + b;
44}
5
6uint32_t foo = 12345;
test/standalone/static_c_lib/foo.h+1
......@@ -1,2 +1,3 @@
11#include <stdint.h>
22uint32_t add(uint32_t a, uint32_t b);
3extern uint32_t foo;
test/standalone/static_c_lib/foo.zig+4
......@@ -6,3 +6,7 @@ test "C add" {
66 const result = c.add(1, 2);
77 expect(result == 3);
88}
9
10test "C extern variable" {
11 expect(c.foo == 12345);
12}