authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-18 22:01:08-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-18 22:01:08-05:00
logc5ca0fe237e105b95c8edb7f80da899012e573f8
tree6f8120d2bb3187a90ba5e855c87332386141bf63
parentcbc4e59e6805d27f0e889c0a9ff8488376cea5c0
parentd7968c6d33b054a8293edd89ce248f385e108469
signaturelock-open Commit is signed but in an unrecognized format.

Merge branch 'pixelherodev-emit'

Closes #4418

8 files changed, 225 insertions(+), 207 deletions(-)

lib/std/build.zig+7
...@@ -1155,6 +1155,9 @@ pub const LibExeObjStep = struct {...@@ -1155,6 +1155,9 @@ pub const LibExeObjStep = struct {
1155 frameworks: BufSet,1155 frameworks: BufSet,
1156 verbose_link: bool,1156 verbose_link: bool,
1157 verbose_cc: bool,1157 verbose_cc: bool,
1158 emit_llvm_ir: bool = false,
1159 emit_asm: bool = false,
1160 emit_bin: bool = true,
1158 disable_gen_h: bool,1161 disable_gen_h: bool,
1159 bundle_compiler_rt: bool,1162 bundle_compiler_rt: bool,
1160 disable_stack_probing: bool,1163 disable_stack_probing: bool,
...@@ -1941,6 +1944,10 @@ pub const LibExeObjStep = struct {...@@ -1941,6 +1944,10 @@ pub const LibExeObjStep = struct {
1941 if (builder.verbose_link or self.verbose_link) zig_args.append("--verbose-link") catch unreachable;1944 if (builder.verbose_link or self.verbose_link) zig_args.append("--verbose-link") catch unreachable;
1942 if (builder.verbose_cc or self.verbose_cc) zig_args.append("--verbose-cc") catch unreachable;1945 if (builder.verbose_cc or self.verbose_cc) zig_args.append("--verbose-cc") catch unreachable;
19431946
1947 if (self.emit_llvm_ir) try zig_args.append("-femit-llvm-ir");
1948 if (self.emit_asm) try zig_args.append("-femit-asm");
1949 if (!self.emit_bin) try zig_args.append("-fno-emit-bin");
1950
1944 if (self.strip) {1951 if (self.strip) {
1945 try zig_args.append("--strip");1952 try zig_args.append("--strip");
1946 }1953 }
src/all_types.hpp+6-9
...@@ -1966,12 +1966,6 @@ enum CodeModel {...@@ -1966,12 +1966,6 @@ enum CodeModel {
1966 CodeModelLarge,1966 CodeModelLarge,
1967};1967};
19681968
1969enum EmitFileType {
1970 EmitFileTypeBinary,
1971 EmitFileTypeAssembly,
1972 EmitFileTypeLLVMIr,
1973};
1974
1975struct LinkLib {1969struct LinkLib {
1976 Buf *name;1970 Buf *name;
1977 Buf *path;1971 Buf *path;
...@@ -2142,8 +2136,10 @@ struct CodeGen {...@@ -2142,8 +2136,10 @@ struct CodeGen {
21422136
2143 Buf llvm_triple_str;2137 Buf llvm_triple_str;
2144 Buf global_asm;2138 Buf global_asm;
2145 Buf output_file_path;
2146 Buf o_file_output_path;2139 Buf o_file_output_path;
2140 Buf bin_file_output_path;
2141 Buf asm_file_output_path;
2142 Buf llvm_ir_file_output_path;
2147 Buf *cache_dir;2143 Buf *cache_dir;
2148 // As an input parameter, mutually exclusive with enable_cache. But it gets2144 // As an input parameter, mutually exclusive with enable_cache. But it gets
2149 // populated in codegen_build_and_link.2145 // populated in codegen_build_and_link.
...@@ -2236,7 +2232,6 @@ struct CodeGen {...@@ -2236,7 +2232,6 @@ struct CodeGen {
2236 size_t version_patch;2232 size_t version_patch;
2237 const char *linker_script;2233 const char *linker_script;
22382234
2239 EmitFileType emit_file_type;
2240 BuildMode build_mode;2235 BuildMode build_mode;
2241 OutType out_type;2236 OutType out_type;
2242 const ZigTarget *zig_target;2237 const ZigTarget *zig_target;
...@@ -2258,7 +2253,9 @@ struct CodeGen {...@@ -2258,7 +2253,9 @@ struct CodeGen {
2258 bool function_sections;2253 bool function_sections;
2259 bool enable_dump_analysis;2254 bool enable_dump_analysis;
2260 bool enable_doc_generation;2255 bool enable_doc_generation;
2261 bool disable_bin_generation;2256 bool emit_bin;
2257 bool emit_asm;
2258 bool emit_llvm_ir;
2262 bool test_is_evented;2259 bool test_is_evented;
2263 CodeModel code_model;2260 CodeModel code_model;
22642261
src/codegen.cpp+84-95
...@@ -121,10 +121,6 @@ void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patc...@@ -121,10 +121,6 @@ void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patc
121 g->version_patch = patch;121 g->version_patch = patch;
122}122}
123123
124void codegen_set_emit_file_type(CodeGen *g, EmitFileType emit_file_type) {
125 g->emit_file_type = emit_file_type;
126}
127
128void codegen_set_each_lib_rpath(CodeGen *g, bool each_lib_rpath) {124void codegen_set_each_lib_rpath(CodeGen *g, bool each_lib_rpath) {
129 g->each_lib_rpath = each_lib_rpath;125 g->each_lib_rpath = each_lib_rpath;
130}126}
...@@ -7925,50 +7921,44 @@ static void zig_llvm_emit_output(CodeGen *g) {...@@ -7925,50 +7921,44 @@ static void zig_llvm_emit_output(CodeGen *g) {
79257921
7926 bool is_small = g->build_mode == BuildModeSmallRelease;7922 bool is_small = g->build_mode == BuildModeSmallRelease;
79277923
7928 Buf *output_path = &g->o_file_output_path;
7929 char *err_msg = nullptr;7924 char *err_msg = nullptr;
7930 switch (g->emit_file_type) {7925 const char *asm_filename = nullptr;
7931 case EmitFileTypeBinary:7926 const char *bin_filename = nullptr;
7932 if (g->disable_bin_generation)7927 const char *llvm_ir_filename = nullptr;
7933 return;7928
7934 if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path),7929 if (g->emit_bin) bin_filename = buf_ptr(&g->o_file_output_path);
7935 ZigLLVM_EmitBinary, &err_msg, g->build_mode == BuildModeDebug, is_small,7930 if (g->emit_asm) asm_filename = buf_ptr(&g->asm_file_output_path);
7936 g->enable_time_report))7931 if (g->emit_llvm_ir) llvm_ir_filename = buf_ptr(&g->llvm_ir_file_output_path);
7937 {7932
7938 zig_panic("unable to write object file %s: %s", buf_ptr(output_path), err_msg);7933 // Unfortunately, LLVM shits the bed when we ask for both binary and assembly. So we call the entire
7939 }7934 // pipeline multiple times if this is requested.
7940 validate_inline_fns(g);7935 if (asm_filename != nullptr && bin_filename != nullptr) {
7941 g->link_objects.append(output_path);7936 if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, &err_msg, g->build_mode == BuildModeDebug,
7942 if (g->bundle_compiler_rt && (g->out_type == OutTypeObj ||7937 is_small, g->enable_time_report, nullptr, bin_filename, llvm_ir_filename))
7943 (g->out_type == OutTypeLib && !g->is_dynamic)))7938 {
7944 {7939 fprintf(stderr, "LLVM failed to emit file: %s\n", err_msg);
7945 zig_link_add_compiler_rt(g, g->sub_progress_node);7940 exit(1);
7946 }7941 }
7947 break;7942 bin_filename = nullptr;
7943 llvm_ir_filename = nullptr;
7944 }
79487945
7949 case EmitFileTypeAssembly:7946 if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, &err_msg, g->build_mode == BuildModeDebug,
7950 if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path),7947 is_small, g->enable_time_report, asm_filename, bin_filename, llvm_ir_filename))
7951 ZigLLVM_EmitAssembly, &err_msg, g->build_mode == BuildModeDebug, is_small,7948 {
7952 g->enable_time_report))7949 fprintf(stderr, "LLVM failed to emit file: %s\n", err_msg);
7953 {7950 exit(1);
7954 zig_panic("unable to write assembly file %s: %s", buf_ptr(output_path), err_msg);7951 }
7955 }
7956 validate_inline_fns(g);
7957 break;
79587952
7959 case EmitFileTypeLLVMIr:7953 validate_inline_fns(g);
7960 if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path),
7961 ZigLLVM_EmitLLVMIr, &err_msg, g->build_mode == BuildModeDebug, is_small,
7962 g->enable_time_report))
7963 {
7964 zig_panic("unable to write llvm-ir file %s: %s", buf_ptr(output_path), err_msg);
7965 }
7966 validate_inline_fns(g);
7967 break;
79687954
7969 default:7955 if (g->emit_bin) {
7970 zig_unreachable();7956 g->link_objects.append(&g->o_file_output_path);
7957 if (g->bundle_compiler_rt && (g->out_type == OutTypeObj || (g->out_type == OutTypeLib && !g->is_dynamic))) {
7958 zig_link_add_compiler_rt(g, g->sub_progress_node);
7959 }
7971 }7960 }
7961
7972 LLVMDisposeModule(g->module);7962 LLVMDisposeModule(g->module);
7973 g->module = nullptr;7963 g->module = nullptr;
7974 LLVMDisposeTargetData(g->target_data_ref);7964 LLVMDisposeTargetData(g->target_data_ref);
...@@ -10450,7 +10440,9 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {...@@ -10450,7 +10440,9 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
10450 cache_bool(ch, g->function_sections);10440 cache_bool(ch, g->function_sections);
10451 cache_bool(ch, g->enable_dump_analysis);10441 cache_bool(ch, g->enable_dump_analysis);
10452 cache_bool(ch, g->enable_doc_generation);10442 cache_bool(ch, g->enable_doc_generation);
10453 cache_bool(ch, g->disable_bin_generation);10443 cache_bool(ch, g->emit_bin);
10444 cache_bool(ch, g->emit_llvm_ir);
10445 cache_bool(ch, g->emit_asm);
10454 cache_buf_opt(ch, g->mmacosx_version_min);10446 cache_buf_opt(ch, g->mmacosx_version_min);
10455 cache_buf_opt(ch, g->mios_version_min);10447 cache_buf_opt(ch, g->mios_version_min);
10456 cache_usize(ch, g->version_major);10448 cache_usize(ch, g->version_major);
...@@ -10495,58 +10487,54 @@ static void resolve_out_paths(CodeGen *g) {...@@ -10495,58 +10487,54 @@ static void resolve_out_paths(CodeGen *g) {
10495 assert(g->output_dir != nullptr);10487 assert(g->output_dir != nullptr);
10496 assert(g->root_out_name != nullptr);10488 assert(g->root_out_name != nullptr);
1049710489
10498 Buf *out_basename = buf_create_from_buf(g->root_out_name);10490 if (g->emit_bin) {
10499 Buf *o_basename = buf_create_from_buf(g->root_out_name);10491 Buf *out_basename = buf_create_from_buf(g->root_out_name);
10500 switch (g->emit_file_type) {10492 Buf *o_basename = buf_create_from_buf(g->root_out_name);
10501 case EmitFileTypeBinary: {10493 switch (g->out_type) {
10502 switch (g->out_type) {10494 case OutTypeUnknown:
10503 case OutTypeUnknown:10495 zig_unreachable();
10504 zig_unreachable();10496 case OutTypeObj:
10505 case OutTypeObj:10497 if (g->enable_cache && g->link_objects.length == 1 && !need_llvm_module(g)) {
10506 if (g->enable_cache && g->link_objects.length == 1 && !need_llvm_module(g)) {10498 buf_init_from_buf(&g->bin_file_output_path, g->link_objects.at(0));
10507 buf_init_from_buf(&g->output_file_path, g->link_objects.at(0));10499 return;
10508 return;10500 }
10509 }10501 if (need_llvm_module(g) && g->link_objects.length != 0 && !g->enable_cache &&
10510 if (need_llvm_module(g) && g->link_objects.length != 0 && !g->enable_cache &&10502 buf_eql_buf(o_basename, out_basename))
10511 buf_eql_buf(o_basename, out_basename))10503 {
10512 {10504 // make it not collide with main output object
10513 // make it not collide with main output object10505 buf_append_str(o_basename, ".root");
10514 buf_append_str(o_basename, ".root");10506 }
10515 }10507 buf_append_str(o_basename, target_o_file_ext(g->zig_target));
10516 buf_append_str(o_basename, target_o_file_ext(g->zig_target));10508 buf_append_str(out_basename, target_o_file_ext(g->zig_target));
10517 buf_append_str(out_basename, target_o_file_ext(g->zig_target));10509 break;
10518 break;10510 case OutTypeExe:
10519 case OutTypeExe:10511 buf_append_str(o_basename, target_o_file_ext(g->zig_target));
10520 buf_append_str(o_basename, target_o_file_ext(g->zig_target));10512 buf_append_str(out_basename, target_exe_file_ext(g->zig_target));
10521 buf_append_str(out_basename, target_exe_file_ext(g->zig_target));10513 break;
10522 break;10514 case OutTypeLib:
10523 case OutTypeLib:10515 buf_append_str(o_basename, target_o_file_ext(g->zig_target));
10524 buf_append_str(o_basename, target_o_file_ext(g->zig_target));10516 buf_resize(out_basename, 0);
10525 buf_resize(out_basename, 0);10517 buf_append_str(out_basename, target_lib_file_prefix(g->zig_target));
10526 buf_append_str(out_basename, target_lib_file_prefix(g->zig_target));10518 buf_append_buf(out_basename, g->root_out_name);
10527 buf_append_buf(out_basename, g->root_out_name);10519 buf_append_str(out_basename, target_lib_file_ext(g->zig_target, !g->is_dynamic,
10528 buf_append_str(out_basename, target_lib_file_ext(g->zig_target, !g->is_dynamic,10520 g->version_major, g->version_minor, g->version_patch));
10529 g->version_major, g->version_minor, g->version_patch));10521 break;
10530 break;
10531 }
10532 break;
10533 }
10534 case EmitFileTypeAssembly: {
10535 const char *asm_ext = target_asm_file_ext(g->zig_target);
10536 buf_append_str(o_basename, asm_ext);
10537 buf_append_str(out_basename, asm_ext);
10538 break;
10539 }
10540 case EmitFileTypeLLVMIr: {
10541 const char *llvm_ir_ext = target_llvm_ir_file_ext(g->zig_target);
10542 buf_append_str(o_basename, llvm_ir_ext);
10543 buf_append_str(out_basename, llvm_ir_ext);
10544 break;
10545 }10522 }
10523 os_path_join(g->output_dir, o_basename, &g->o_file_output_path);
10524 os_path_join(g->output_dir, out_basename, &g->bin_file_output_path);
10525 }
10526 if (g->emit_asm) {
10527 Buf *asm_basename = buf_create_from_buf(g->root_out_name);
10528 const char *asm_ext = target_asm_file_ext(g->zig_target);
10529 buf_append_str(asm_basename, asm_ext);
10530 os_path_join(g->output_dir, asm_basename, &g->asm_file_output_path);
10531 }
10532 if (g->emit_llvm_ir) {
10533 Buf *llvm_ir_basename = buf_create_from_buf(g->root_out_name);
10534 const char *llvm_ir_ext = target_llvm_ir_file_ext(g->zig_target);
10535 buf_append_str(llvm_ir_basename, llvm_ir_ext);
10536 os_path_join(g->output_dir, llvm_ir_basename, &g->llvm_ir_file_output_path);
10546 }10537 }
10547
10548 os_path_join(g->output_dir, o_basename, &g->o_file_output_path);
10549 os_path_join(g->output_dir, out_basename, &g->output_file_path);
10550}10538}
1055110539
10552void codegen_build_and_link(CodeGen *g) {10540void codegen_build_and_link(CodeGen *g) {
...@@ -10708,7 +10696,7 @@ void codegen_build_and_link(CodeGen *g) {...@@ -10708,7 +10696,7 @@ void codegen_build_and_link(CodeGen *g) {
10708 // If there is more than one object, we have to link them (with -r).10696 // If there is more than one object, we have to link them (with -r).
10709 // Finally, if we didn't make an object from zig source, and we don't have caching enabled,10697 // Finally, if we didn't make an object from zig source, and we don't have caching enabled,
10710 // then we have an object from C source that we must copy to the output dir which we do with a -r link.10698 // then we have an object from C source that we must copy to the output dir which we do with a -r link.
10711 if (!g->disable_bin_generation && g->emit_file_type == EmitFileTypeBinary &&10699 if (g->emit_bin &&
10712 (g->out_type != OutTypeObj || g->link_objects.length > 1 ||10700 (g->out_type != OutTypeObj || g->link_objects.length > 1 ||
10713 (!need_llvm_module(g) && !g->enable_cache)))10701 (!need_llvm_module(g) && !g->enable_cache)))
10714 {10702 {
...@@ -10786,6 +10774,7 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget...@@ -10786,6 +10774,7 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget
10786 Stage2LibCInstallation *libc, Buf *cache_dir, bool is_test_build, Stage2ProgressNode *progress_node)10774 Stage2LibCInstallation *libc, Buf *cache_dir, bool is_test_build, Stage2ProgressNode *progress_node)
10787{10775{
10788 CodeGen *g = heap::c_allocator.create<CodeGen>();10776 CodeGen *g = heap::c_allocator.create<CodeGen>();
10777 g->emit_bin = true;
10789 g->pass1_arena = heap::ArenaAllocator::construct(&heap::c_allocator, &heap::c_allocator, "pass1");10778 g->pass1_arena = heap::ArenaAllocator::construct(&heap::c_allocator, &heap::c_allocator, "pass1");
10790 g->main_progress_node = progress_node;10779 g->main_progress_node = progress_node;
1079110780
src/codegen.hpp-1
...@@ -26,7 +26,6 @@ void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len);...@@ -26,7 +26,6 @@ void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len);
26void codegen_set_llvm_argv(CodeGen *codegen, const char **args, size_t len);26void codegen_set_llvm_argv(CodeGen *codegen, const char **args, size_t len);
27void codegen_set_each_lib_rpath(CodeGen *codegen, bool each_lib_rpath);27void codegen_set_each_lib_rpath(CodeGen *codegen, bool each_lib_rpath);
2828
29void codegen_set_emit_file_type(CodeGen *g, EmitFileType emit_file_type);
30void codegen_set_strip(CodeGen *codegen, bool strip);29void codegen_set_strip(CodeGen *codegen, bool strip);
31void codegen_set_errmsg_color(CodeGen *codegen, ErrColor err_color);30void codegen_set_errmsg_color(CodeGen *codegen, ErrColor err_color);
32void codegen_set_out_name(CodeGen *codegen, Buf *out_name);31void codegen_set_out_name(CodeGen *codegen, Buf *out_name);
src/link.cpp+19-19
...@@ -605,7 +605,7 @@ static const char *build_libc_object(CodeGen *parent_gen, const char *name, CFil...@@ -605,7 +605,7 @@ static const char *build_libc_object(CodeGen *parent_gen, const char *name, CFil
605 c_source_files.append(c_file);605 c_source_files.append(c_file);
606 child_gen->c_source_files = c_source_files;606 child_gen->c_source_files = c_source_files;
607 codegen_build_and_link(child_gen);607 codegen_build_and_link(child_gen);
608 return buf_ptr(&child_gen->output_file_path);608 return buf_ptr(&child_gen->bin_file_output_path);
609}609}
610610
611static const char *path_from_zig_lib(CodeGen *g, const char *dir, const char *subpath) {611static const char *path_from_zig_lib(CodeGen *g, const char *dir, const char *subpath) {
...@@ -682,7 +682,7 @@ static const char *build_libunwind(CodeGen *parent, Stage2ProgressNode *progress...@@ -682,7 +682,7 @@ static const char *build_libunwind(CodeGen *parent, Stage2ProgressNode *progress
682 }682 }
683 child_gen->c_source_files = c_source_files;683 child_gen->c_source_files = c_source_files;
684 codegen_build_and_link(child_gen);684 codegen_build_and_link(child_gen);
685 return buf_ptr(&child_gen->output_file_path);685 return buf_ptr(&child_gen->bin_file_output_path);
686}686}
687687
688static void mingw_add_cc_args(CodeGen *parent, CFile *c_file) {688static void mingw_add_cc_args(CodeGen *parent, CFile *c_file) {
...@@ -1123,7 +1123,7 @@ static const char *build_musl(CodeGen *parent, Stage2ProgressNode *progress_node...@@ -1123,7 +1123,7 @@ static const char *build_musl(CodeGen *parent, Stage2ProgressNode *progress_node
11231123
1124 child_gen->c_source_files = c_source_files;1124 child_gen->c_source_files = c_source_files;
1125 codegen_build_and_link(child_gen);1125 codegen_build_and_link(child_gen);
1126 return buf_ptr(&child_gen->output_file_path);1126 return buf_ptr(&child_gen->bin_file_output_path);
1127}1127}
11281128
1129static void add_msvcrt_os_dep(CodeGen *parent, CodeGen *child_gen, const char *src_path) {1129static void add_msvcrt_os_dep(CodeGen *parent, CodeGen *child_gen, const char *src_path) {
...@@ -1253,7 +1253,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr...@@ -1253,7 +1253,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
1253 child_gen->c_source_files.append(c_file);1253 child_gen->c_source_files.append(c_file);
1254 }1254 }
1255 codegen_build_and_link(child_gen);1255 codegen_build_and_link(child_gen);
1256 return buf_ptr(&child_gen->output_file_path);1256 return buf_ptr(&child_gen->bin_file_output_path);
1257 } else if (strcmp(file, "msvcrt-os.lib") == 0) {1257 } else if (strcmp(file, "msvcrt-os.lib") == 0) {
1258 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "msvcrt-os", progress_node);1258 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "msvcrt-os", progress_node);
12591259
...@@ -1270,7 +1270,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr...@@ -1270,7 +1270,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
1270 }1270 }
1271 }1271 }
1272 codegen_build_and_link(child_gen);1272 codegen_build_and_link(child_gen);
1273 return buf_ptr(&child_gen->output_file_path);1273 return buf_ptr(&child_gen->bin_file_output_path);
1274 } else if (strcmp(file, "mingwex.lib") == 0) {1274 } else if (strcmp(file, "mingwex.lib") == 0) {
1275 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "mingwex", progress_node);1275 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "mingwex", progress_node);
12761276
...@@ -1295,7 +1295,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr...@@ -1295,7 +1295,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
1295 zig_unreachable();1295 zig_unreachable();
1296 }1296 }
1297 codegen_build_and_link(child_gen);1297 codegen_build_and_link(child_gen);
1298 return buf_ptr(&child_gen->output_file_path);1298 return buf_ptr(&child_gen->bin_file_output_path);
1299 } else {1299 } else {
1300 zig_unreachable();1300 zig_unreachable();
1301 }1301 }
...@@ -1365,7 +1365,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr...@@ -1365,7 +1365,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
1365 codegen_add_object(child_gen, buf_create_from_str(start_os));1365 codegen_add_object(child_gen, buf_create_from_str(start_os));
1366 codegen_add_object(child_gen, buf_create_from_str(abi_note_o));1366 codegen_add_object(child_gen, buf_create_from_str(abi_note_o));
1367 codegen_build_and_link(child_gen);1367 codegen_build_and_link(child_gen);
1368 return buf_ptr(&child_gen->output_file_path);1368 return buf_ptr(&child_gen->bin_file_output_path);
1369 } else if (strcmp(file, "libc_nonshared.a") == 0) {1369 } else if (strcmp(file, "libc_nonshared.a") == 0) {
1370 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "c_nonshared", progress_node);1370 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "c_nonshared", progress_node);
1371 {1371 {
...@@ -1445,7 +1445,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr...@@ -1445,7 +1445,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
1445 build_libc_object(parent, deps[i].name, c_file, progress_node)));1445 build_libc_object(parent, deps[i].name, c_file, progress_node)));
1446 }1446 }
1447 codegen_build_and_link(child_gen);1447 codegen_build_and_link(child_gen);
1448 return buf_ptr(&child_gen->output_file_path);1448 return buf_ptr(&child_gen->bin_file_output_path);
1449 } else {1449 } else {
1450 zig_unreachable();1450 zig_unreachable();
1451 }1451 }
...@@ -1519,7 +1519,7 @@ static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path,...@@ -1519,7 +1519,7 @@ static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path,
1519 child_gen->want_stack_check = WantStackCheckDisabled;1519 child_gen->want_stack_check = WantStackCheckDisabled;
15201520
1521 codegen_build_and_link(child_gen);1521 codegen_build_and_link(child_gen);
1522 return &child_gen->output_file_path;1522 return &child_gen->bin_file_output_path;
1523}1523}
15241524
1525static Buf *build_compiler_rt(CodeGen *parent_gen, OutType child_out_type, Stage2ProgressNode *progress_node) {1525static Buf *build_compiler_rt(CodeGen *parent_gen, OutType child_out_type, Stage2ProgressNode *progress_node) {
...@@ -1681,7 +1681,7 @@ static void construct_linker_job_elf(LinkJob *lj) {...@@ -1681,7 +1681,7 @@ static void construct_linker_job_elf(LinkJob *lj) {
1681 } else if (is_dyn_lib) {1681 } else if (is_dyn_lib) {
1682 lj->args.append("-shared");1682 lj->args.append("-shared");
16831683
1684 assert(buf_len(&g->output_file_path) != 0);1684 assert(buf_len(&g->bin_file_output_path) != 0);
1685 soname = buf_sprintf("lib%s.so.%" ZIG_PRI_usize, buf_ptr(g->root_out_name), g->version_major);1685 soname = buf_sprintf("lib%s.so.%" ZIG_PRI_usize, buf_ptr(g->root_out_name), g->version_major);
1686 }1686 }
16871687
...@@ -1690,7 +1690,7 @@ static void construct_linker_job_elf(LinkJob *lj) {...@@ -1690,7 +1690,7 @@ static void construct_linker_job_elf(LinkJob *lj) {
1690 }1690 }
16911691
1692 lj->args.append("-o");1692 lj->args.append("-o");
1693 lj->args.append(buf_ptr(&g->output_file_path));1693 lj->args.append(buf_ptr(&g->bin_file_output_path));
16941694
1695 if (lj->link_in_crt) {1695 if (lj->link_in_crt) {
1696 const char *crt1o;1696 const char *crt1o;
...@@ -1872,7 +1872,7 @@ static void construct_linker_job_wasm(LinkJob *lj) {...@@ -1872,7 +1872,7 @@ static void construct_linker_job_wasm(LinkJob *lj) {
1872 }1872 }
1873 lj->args.append("--allow-undefined");1873 lj->args.append("--allow-undefined");
1874 lj->args.append("-o");1874 lj->args.append("-o");
1875 lj->args.append(buf_ptr(&g->output_file_path));1875 lj->args.append(buf_ptr(&g->bin_file_output_path));
18761876
1877 // .o files1877 // .o files
1878 for (size_t i = 0; i < g->link_objects.length; i += 1) {1878 for (size_t i = 0; i < g->link_objects.length; i += 1) {
...@@ -2248,7 +2248,7 @@ static void construct_linker_job_coff(LinkJob *lj) {...@@ -2248,7 +2248,7 @@ static void construct_linker_job_coff(LinkJob *lj) {
2248 lj->args.append("-DLL");2248 lj->args.append("-DLL");
2249 }2249 }
22502250
2251 lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->output_file_path))));2251 lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->bin_file_output_path))));
22522252
2253 if (g->libc_link_lib != nullptr && g->libc != nullptr) {2253 if (g->libc_link_lib != nullptr && g->libc != nullptr) {
2254 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->crt_dir)));2254 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->crt_dir)));
...@@ -2501,7 +2501,7 @@ static void construct_linker_job_macho(LinkJob *lj) {...@@ -2501,7 +2501,7 @@ static void construct_linker_job_macho(LinkJob *lj) {
2501 //lj->args.append("-install_name");2501 //lj->args.append("-install_name");
2502 //lj->args.append(buf_ptr(dylib_install_name));2502 //lj->args.append(buf_ptr(dylib_install_name));
25032503
2504 assert(buf_len(&g->output_file_path) != 0);2504 assert(buf_len(&g->bin_file_output_path) != 0);
2505 }2505 }
25062506
2507 lj->args.append("-arch");2507 lj->args.append("-arch");
...@@ -2532,14 +2532,14 @@ static void construct_linker_job_macho(LinkJob *lj) {...@@ -2532,14 +2532,14 @@ static void construct_linker_job_macho(LinkJob *lj) {
2532 }2532 }
25332533
2534 lj->args.append("-o");2534 lj->args.append("-o");
2535 lj->args.append(buf_ptr(&g->output_file_path));2535 lj->args.append(buf_ptr(&g->bin_file_output_path));
25362536
2537 for (size_t i = 0; i < g->rpath_list.length; i += 1) {2537 for (size_t i = 0; i < g->rpath_list.length; i += 1) {
2538 Buf *rpath = g->rpath_list.at(i);2538 Buf *rpath = g->rpath_list.at(i);
2539 add_rpath(lj, rpath);2539 add_rpath(lj, rpath);
2540 }2540 }
2541 if (is_dyn_lib) {2541 if (is_dyn_lib) {
2542 add_rpath(lj, &g->output_file_path);2542 add_rpath(lj, &g->bin_file_output_path);
2543 }2543 }
25442544
2545 if (is_dyn_lib) {2545 if (is_dyn_lib) {
...@@ -2659,14 +2659,14 @@ void codegen_link(CodeGen *g) {...@@ -2659,14 +2659,14 @@ void codegen_link(CodeGen *g) {
2659 progress_name, strlen(progress_name), 0));2659 progress_name, strlen(progress_name), 0));
2660 }2660 }
2661 if (g->verbose_link) {2661 if (g->verbose_link) {
2662 fprintf(stderr, "ar rcs %s", buf_ptr(&g->output_file_path));2662 fprintf(stderr, "ar rcs %s", buf_ptr(&g->bin_file_output_path));
2663 for (size_t i = 0; i < file_names.length; i += 1) {2663 for (size_t i = 0; i < file_names.length; i += 1) {
2664 fprintf(stderr, " %s", file_names.at(i));2664 fprintf(stderr, " %s", file_names.at(i));
2665 }2665 }
2666 fprintf(stderr, "\n");2666 fprintf(stderr, "\n");
2667 }2667 }
2668 if (ZigLLVMWriteArchive(buf_ptr(&g->output_file_path), file_names.items, file_names.length, os_type)) {2668 if (ZigLLVMWriteArchive(buf_ptr(&g->bin_file_output_path), file_names.items, file_names.length, os_type)) {
2669 fprintf(stderr, "Unable to write archive '%s'\n", buf_ptr(&g->output_file_path));2669 fprintf(stderr, "Unable to write archive '%s'\n", buf_ptr(&g->bin_file_output_path));
2670 exit(1);2670 exit(1);
2671 }2671 }
2672 return;2672 return;
src/main.cpp+47-31
...@@ -62,17 +62,21 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {...@@ -62,17 +62,21 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
62 " -fno-stack-check disable stack probing in safe builds\n"62 " -fno-stack-check disable stack probing in safe builds\n"
63 " -fsanitize-c enable C undefined behavior detection in unsafe builds\n"63 " -fsanitize-c enable C undefined behavior detection in unsafe builds\n"
64 " -fno-sanitize-c disable C undefined behavior detection in safe builds\n"64 " -fno-sanitize-c disable C undefined behavior detection in safe builds\n"
65 " --emit [asm|bin|llvm-ir] emit a specific file format as compilation output\n"65 " --emit [asm|bin|llvm-ir] (deprecated) emit a specific file format as compilation output\n"
66 " -fPIC enable Position Independent Code\n"66 " -fPIC enable Position Independent Code\n"
67 " -fno-PIC disable Position Independent Code\n"67 " -fno-PIC disable Position Independent Code\n"
68 " -ftime-report print timing diagnostics\n"68 " -ftime-report print timing diagnostics\n"
69 " -fstack-report print stack size diagnostics\n"69 " -fstack-report print stack size diagnostics\n"
70#ifdef ZIG_ENABLE_MEM_PROFILE
71 " -fmem-report print memory usage diagnostics\n"70 " -fmem-report print memory usage diagnostics\n"
72#endif
73 " -fdump-analysis write analysis.json file with type information\n"71 " -fdump-analysis write analysis.json file with type information\n"
74 " -femit-docs create a docs/ dir with html documentation\n"72 " -femit-docs create a docs/ dir with html documentation\n"
75 " -fno-emit-bin skip emitting machine code\n"73 " -fno-emit-docs do not produce docs/ dir with html documentation\n"
74 " -femit-bin (default) output machine code\n"
75 " -fno-emit-bin do not output machine code\n"
76 " -femit-asm output .s (assembly code)\n"
77 " -fno-emit-asm (default) do not output .s (assembly code)\n"
78 " -femit-llvm-ir produce a .ll file with LLVM IR\n"
79 " -fno-emit-llvm-ir (default) do not produce a .ll file with LLVM IR\n"
76 " --libc [file] Provide a file which specifies libc paths\n"80 " --libc [file] Provide a file which specifies libc paths\n"
77 " --name [name] override output name\n"81 " --name [name] override output name\n"
78 " --output-dir [dir] override output directory (defaults to cwd)\n"82 " --output-dir [dir] override output directory (defaults to cwd)\n"
...@@ -376,7 +380,6 @@ static int main0(int argc, char **argv) {...@@ -376,7 +380,6 @@ static int main0(int argc, char **argv) {
376 }380 }
377381
378 Cmd cmd = CmdNone;382 Cmd cmd = CmdNone;
379 EmitFileType emit_file_type = EmitFileTypeBinary;
380 const char *in_file = nullptr;383 const char *in_file = nullptr;
381 Buf *output_dir = nullptr;384 Buf *output_dir = nullptr;
382 bool strip = false;385 bool strip = false;
...@@ -424,7 +427,9 @@ static int main0(int argc, char **argv) {...@@ -424,7 +427,9 @@ static int main0(int argc, char **argv) {
424 bool stack_report = false;427 bool stack_report = false;
425 bool enable_dump_analysis = false;428 bool enable_dump_analysis = false;
426 bool enable_doc_generation = false;429 bool enable_doc_generation = false;
427 bool disable_bin_generation = false;430 bool emit_bin = true;
431 bool emit_asm = false;
432 bool emit_llvm_ir = false;
428 const char *cache_dir = nullptr;433 const char *cache_dir = nullptr;
429 CliPkg *cur_pkg = heap::c_allocator.create<CliPkg>();434 CliPkg *cur_pkg = heap::c_allocator.create<CliPkg>();
430 BuildMode build_mode = BuildModeDebug;435 BuildMode build_mode = BuildModeDebug;
...@@ -552,7 +557,7 @@ static int main0(int argc, char **argv) {...@@ -552,7 +557,7 @@ static int main0(int argc, char **argv) {
552 }557 }
553558
554 Termination term;559 Termination term;
555 args.items[0] = buf_ptr(&g->output_file_path);560 args.items[0] = buf_ptr(&g->bin_file_output_path);
556 os_spawn_process(args, &term);561 os_spawn_process(args, &term);
557 if (term.how != TerminationIdClean || term.code != 0) {562 if (term.how != TerminationIdClean || term.code != 0) {
558 fprintf(stderr, "\nBuild failed. The following command failed:\n");563 fprintf(stderr, "\nBuild failed. The following command failed:\n");
...@@ -631,8 +636,6 @@ static int main0(int argc, char **argv) {...@@ -631,8 +636,6 @@ static int main0(int argc, char **argv) {
631 enable_dump_analysis = true;636 enable_dump_analysis = true;
632 } else if (strcmp(arg, "-femit-docs") == 0) {637 } else if (strcmp(arg, "-femit-docs") == 0) {
633 enable_doc_generation = true;638 enable_doc_generation = true;
634 } else if (strcmp(arg, "-fno-emit-bin") == 0) {
635 disable_bin_generation = true;
636 } else if (strcmp(arg, "--enable-valgrind") == 0) {639 } else if (strcmp(arg, "--enable-valgrind") == 0) {
637 valgrind_support = ValgrindSupportEnabled;640 valgrind_support = ValgrindSupportEnabled;
638 } else if (strcmp(arg, "--disable-valgrind") == 0) {641 } else if (strcmp(arg, "--disable-valgrind") == 0) {
...@@ -701,6 +704,18 @@ static int main0(int argc, char **argv) {...@@ -701,6 +704,18 @@ static int main0(int argc, char **argv) {
701 function_sections = true;704 function_sections = true;
702 } else if (strcmp(arg, "--test-evented-io") == 0) {705 } else if (strcmp(arg, "--test-evented-io") == 0) {
703 test_evented_io = true;706 test_evented_io = true;
707 } else if (strcmp(arg, "-femit-bin") == 0) {
708 emit_bin = true;
709 } else if (strcmp(arg, "-fno-emit-bin") == 0) {
710 emit_bin = false;
711 } else if (strcmp(arg, "-femit-asm") == 0) {
712 emit_asm = true;
713 } else if (strcmp(arg, "-fno-emit-asm") == 0) {
714 emit_asm = false;
715 } else if (strcmp(arg, "-femit-llvm-ir") == 0) {
716 emit_llvm_ir = true;
717 } else if (strcmp(arg, "-fno-emit-llvm-ir") == 0) {
718 emit_llvm_ir = false;
704 } else if (i + 1 >= argc) {719 } else if (i + 1 >= argc) {
705 fprintf(stderr, "Expected another argument after %s\n", arg);720 fprintf(stderr, "Expected another argument after %s\n", arg);
706 return print_error_usage(arg0);721 return print_error_usage(arg0);
...@@ -732,11 +747,13 @@ static int main0(int argc, char **argv) {...@@ -732,11 +747,13 @@ static int main0(int argc, char **argv) {
732 }747 }
733 } else if (strcmp(arg, "--emit") == 0) {748 } else if (strcmp(arg, "--emit") == 0) {
734 if (strcmp(argv[i], "asm") == 0) {749 if (strcmp(argv[i], "asm") == 0) {
735 emit_file_type = EmitFileTypeAssembly;750 emit_asm = true;
751 emit_bin = false;
736 } else if (strcmp(argv[i], "bin") == 0) {752 } else if (strcmp(argv[i], "bin") == 0) {
737 emit_file_type = EmitFileTypeBinary;753 emit_bin = true;
738 } else if (strcmp(argv[i], "llvm-ir") == 0) {754 } else if (strcmp(argv[i], "llvm-ir") == 0) {
739 emit_file_type = EmitFileTypeLLVMIr;755 emit_llvm_ir = true;
756 emit_bin = false;
740 } else {757 } else {
741 fprintf(stderr, "--emit options are 'asm', 'bin', or 'llvm-ir'\n");758 fprintf(stderr, "--emit options are 'asm', 'bin', or 'llvm-ir'\n");
742 return print_error_usage(arg0);759 return print_error_usage(arg0);
...@@ -1026,8 +1043,8 @@ static int main0(int argc, char **argv) {...@@ -1026,8 +1043,8 @@ static int main0(int argc, char **argv) {
1026 return print_error_usage(arg0);1043 return print_error_usage(arg0);
1027 }1044 }
10281045
1029 if (emit_file_type != EmitFileTypeBinary && in_file == nullptr) {1046 if ((emit_asm || emit_llvm_ir) && in_file == nullptr) {
1030 fprintf(stderr, "A root source file is required when using `--emit asm` or `--emit llvm-ir`\n");1047 fprintf(stderr, "A root source file is required when using `-femit-asm` or `-femit-llvm-ir`\n");
1031 return print_error_usage(arg0);1048 return print_error_usage(arg0);
1032 }1049 }
10331050
...@@ -1098,8 +1115,8 @@ static int main0(int argc, char **argv) {...@@ -1098,8 +1115,8 @@ static int main0(int argc, char **argv) {
1098 {1115 {
1099 fprintf(stderr, "Expected source file argument.\n");1116 fprintf(stderr, "Expected source file argument.\n");
1100 return print_error_usage(arg0);1117 return print_error_usage(arg0);
1101 } else if (cmd == CmdRun && emit_file_type != EmitFileTypeBinary) {1118 } else if (cmd == CmdRun && !emit_bin) {
1102 fprintf(stderr, "Cannot run non-executable file.\n");1119 fprintf(stderr, "Cannot run without emitting a binary file.\n");
1103 return print_error_usage(arg0);1120 return print_error_usage(arg0);
1104 }1121 }
11051122
...@@ -1176,7 +1193,10 @@ static int main0(int argc, char **argv) {...@@ -1176,7 +1193,10 @@ static int main0(int argc, char **argv) {
1176 g->enable_stack_report = stack_report;1193 g->enable_stack_report = stack_report;
1177 g->enable_dump_analysis = enable_dump_analysis;1194 g->enable_dump_analysis = enable_dump_analysis;
1178 g->enable_doc_generation = enable_doc_generation;1195 g->enable_doc_generation = enable_doc_generation;
1179 g->disable_bin_generation = disable_bin_generation;1196 g->emit_bin = emit_bin;
1197 g->emit_asm = emit_asm;
1198 g->emit_llvm_ir = emit_llvm_ir;
1199
1180 codegen_set_out_name(g, buf_out_name);1200 codegen_set_out_name(g, buf_out_name);
1181 codegen_set_lib_version(g, ver_major, ver_minor, ver_patch);1201 codegen_set_lib_version(g, ver_major, ver_minor, ver_patch);
1182 g->want_single_threaded = want_single_threaded;1202 g->want_single_threaded = want_single_threaded;
...@@ -1262,8 +1282,6 @@ static int main0(int argc, char **argv) {...@@ -1262,8 +1282,6 @@ static int main0(int argc, char **argv) {
12621282
12631283
1264 if (cmd == CmdBuild || cmd == CmdRun) {1284 if (cmd == CmdBuild || cmd == CmdRun) {
1265 codegen_set_emit_file_type(g, emit_file_type);
1266
1267 g->enable_cache = get_cache_opt(enable_cache, cmd == CmdRun);1285 g->enable_cache = get_cache_opt(enable_cache, cmd == CmdRun);
1268 codegen_build_and_link(g);1286 codegen_build_and_link(g);
1269 if (root_progress_node != nullptr) {1287 if (root_progress_node != nullptr) {
...@@ -1281,7 +1299,7 @@ static int main0(int argc, char **argv) {...@@ -1281,7 +1299,7 @@ static int main0(int argc, char **argv) {
1281 mem::print_report();1299 mem::print_report();
1282#endif1300#endif
12831301
1284 const char *exec_path = buf_ptr(&g->output_file_path);1302 const char *exec_path = buf_ptr(&g->bin_file_output_path);
1285 ZigList<const char*> args = {0};1303 ZigList<const char*> args = {0};
12861304
1287 args.append(exec_path);1305 args.append(exec_path);
...@@ -1301,21 +1319,21 @@ static int main0(int argc, char **argv) {...@@ -1301,21 +1319,21 @@ static int main0(int argc, char **argv) {
1301 } else if (cmd == CmdBuild) {1319 } else if (cmd == CmdBuild) {
1302 if (g->enable_cache) {1320 if (g->enable_cache) {
1303#if defined(ZIG_OS_WINDOWS)1321#if defined(ZIG_OS_WINDOWS)
1304 buf_replace(&g->output_file_path, '/', '\\');1322 buf_replace(&g->bin_file_output_path, '/', '\\');
1305#endif1323#endif
1306 if (final_output_dir_step != nullptr) {1324 if (final_output_dir_step != nullptr) {
1307 Buf *dest_basename = buf_alloc();1325 Buf *dest_basename = buf_alloc();
1308 os_path_split(&g->output_file_path, nullptr, dest_basename);1326 os_path_split(&g->bin_file_output_path, nullptr, dest_basename);
1309 Buf *dest_path = buf_alloc();1327 Buf *dest_path = buf_alloc();
1310 os_path_join(final_output_dir_step, dest_basename, dest_path);1328 os_path_join(final_output_dir_step, dest_basename, dest_path);
13111329
1312 if ((err = os_update_file(&g->output_file_path, dest_path))) {1330 if ((err = os_update_file(&g->bin_file_output_path, dest_path))) {
1313 fprintf(stderr, "unable to copy %s to %s: %s\n", buf_ptr(&g->output_file_path),1331 fprintf(stderr, "unable to copy %s to %s: %s\n", buf_ptr(&g->bin_file_output_path),
1314 buf_ptr(dest_path), err_str(err));1332 buf_ptr(dest_path), err_str(err));
1315 return main_exit(root_progress_node, EXIT_FAILURE);1333 return main_exit(root_progress_node, EXIT_FAILURE);
1316 }1334 }
1317 } else {1335 } else {
1318 if (printf("%s\n", buf_ptr(&g->output_file_path)) < 0)1336 if (printf("%s\n", buf_ptr(&g->bin_file_output_path)) < 0)
1319 return main_exit(root_progress_node, EXIT_FAILURE);1337 return main_exit(root_progress_node, EXIT_FAILURE);
1320 }1338 }
1321 }1339 }
...@@ -1330,8 +1348,6 @@ static int main0(int argc, char **argv) {...@@ -1330,8 +1348,6 @@ static int main0(int argc, char **argv) {
1330 codegen_print_timing_report(g, stderr);1348 codegen_print_timing_report(g, stderr);
1331 return main_exit(root_progress_node, EXIT_SUCCESS);1349 return main_exit(root_progress_node, EXIT_SUCCESS);
1332 } else if (cmd == CmdTest) {1350 } else if (cmd == CmdTest) {
1333 codegen_set_emit_file_type(g, emit_file_type);
1334
1335 ZigTarget native;1351 ZigTarget native;
1336 get_native_target(&native);1352 get_native_target(&native);
13371353
...@@ -1350,17 +1366,17 @@ static int main0(int argc, char **argv) {...@@ -1350,17 +1366,17 @@ static int main0(int argc, char **argv) {
1350 zig_print_stack_report(g, stdout);1366 zig_print_stack_report(g, stdout);
1351 }1367 }
13521368
1353 if (g->disable_bin_generation) {1369 if (!g->emit_bin) {
1354 fprintf(stderr, "Semantic analysis complete. No binary produced due to -fno-emit-bin.\n");1370 fprintf(stderr, "Semantic analysis complete. No binary produced due to -fno-emit-bin.\n");
1355 return main_exit(root_progress_node, EXIT_SUCCESS);1371 return main_exit(root_progress_node, EXIT_SUCCESS);
1356 }1372 }
13571373
1358 Buf *test_exe_path_unresolved = &g->output_file_path;1374 Buf *test_exe_path_unresolved = &g->bin_file_output_path;
1359 Buf *test_exe_path = buf_alloc();1375 Buf *test_exe_path = buf_alloc();
1360 *test_exe_path = os_path_resolve(&test_exe_path_unresolved, 1);1376 *test_exe_path = os_path_resolve(&test_exe_path_unresolved, 1);
13611377
1362 if (emit_file_type != EmitFileTypeBinary) {1378 if (!g->emit_bin) {
1363 fprintf(stderr, "Created %s but skipping execution because it is non executable.\n",1379 fprintf(stderr, "Created %s but skipping execution because no binary generated.\n",
1364 buf_ptr(test_exe_path));1380 buf_ptr(test_exe_path));
1365 return main_exit(root_progress_node, EXIT_SUCCESS);1381 return main_exit(root_progress_node, EXIT_SUCCESS);
1366 }1382 }
src/zig_llvm.cpp+59-42
...@@ -161,17 +161,32 @@ unsigned ZigLLVMDataLayoutGetProgramAddressSpace(LLVMTargetDataRef TD) {...@@ -161,17 +161,32 @@ unsigned ZigLLVMDataLayoutGetProgramAddressSpace(LLVMTargetDataRef TD) {
161}161}
162162
163bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,163bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,
164 const char *filename, ZigLLVM_EmitOutputType output_type, char **error_message, bool is_debug,164 char **error_message, bool is_debug,
165 bool is_small, bool time_report)165 bool is_small, bool time_report,
166 const char *asm_filename, const char *bin_filename, const char *llvm_ir_filename)
166{167{
167 TimePassesIsEnabled = time_report;168 TimePassesIsEnabled = time_report;
168169
169 std::error_code EC;170 raw_fd_ostream *dest_asm = nullptr;
170 raw_fd_ostream dest(filename, EC, sys::fs::F_None);171 raw_fd_ostream *dest_bin = nullptr;
171 if (EC) {172
172 *error_message = strdup((const char *)StringRef(EC.message()).bytes_begin());173 if (asm_filename) {
173 return true;174 std::error_code EC;
175 dest_asm = new(std::nothrow) raw_fd_ostream(asm_filename, EC, sys::fs::F_None);
176 if (EC) {
177 *error_message = strdup((const char *)StringRef(EC.message()).bytes_begin());
178 return true;
179 }
174 }180 }
181 if (bin_filename) {
182 std::error_code EC;
183 dest_bin = new(std::nothrow) raw_fd_ostream(bin_filename, EC, sys::fs::F_None);
184 if (EC) {
185 *error_message = strdup((const char *)StringRef(EC.message()).bytes_begin());
186 return true;
187 }
188 }
189
175 TargetMachine* target_machine = reinterpret_cast<TargetMachine*>(targ_machine_ref);190 TargetMachine* target_machine = reinterpret_cast<TargetMachine*>(targ_machine_ref);
176 target_machine->setO0WantsFastISel(true);191 target_machine->setO0WantsFastISel(true);
177192
...@@ -222,49 +237,51 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM...@@ -222,49 +237,51 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM
222 }237 }
223 PMBuilder->populateFunctionPassManager(FPM);238 PMBuilder->populateFunctionPassManager(FPM);
224239
225 // Set up the per-module pass manager.240 {
226 legacy::PassManager MPM;241 // Set up the per-module pass manager.
227 MPM.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis()));242 legacy::PassManager MPM;
228 PMBuilder->populateModulePassManager(MPM);243 MPM.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis()));
229244 PMBuilder->populateModulePassManager(MPM);
230 // Set output pass.245
231 TargetMachine::CodeGenFileType ft;246 // Set output passes.
232 if (output_type != ZigLLVM_EmitLLVMIr) {247 if (dest_bin) {
233 switch (output_type) {248 if (target_machine->addPassesToEmitFile(MPM, *dest_bin, nullptr, TargetMachine::CGFT_ObjectFile)) {
234 case ZigLLVM_EmitAssembly:249 *error_message = strdup("TargetMachine can't emit an object file");
235 ft = TargetMachine::CGFT_AssemblyFile;250 return true;
236 break;251 }
237 case ZigLLVM_EmitBinary:
238 ft = TargetMachine::CGFT_ObjectFile;
239 break;
240 default:
241 abort();
242 }252 }
243253 if (dest_asm) {
244 if (target_machine->addPassesToEmitFile(MPM, dest, nullptr, ft)) {254 if (target_machine->addPassesToEmitFile(MPM, *dest_asm, nullptr, TargetMachine::CGFT_AssemblyFile)) {
245 *error_message = strdup("TargetMachine can't emit a file of this type");255 *error_message = strdup("TargetMachine can't emit an assembly file");
246 return true;256 return true;
257 }
247 }258 }
248 }
249259
250 // run per function optimization passes260 // run per function optimization passes
251 FPM.doInitialization();261 FPM.doInitialization();
252 for (Function &F : *module)262 for (Function &F : *module)
253 if (!F.isDeclaration())263 if (!F.isDeclaration())
254 FPM.run(F);264 FPM.run(F);
255 FPM.doFinalization();265 FPM.doFinalization();
256266
257 MPM.run(*module);267 MPM.run(*module);
258268
259 if (output_type == ZigLLVM_EmitLLVMIr) {269 if (llvm_ir_filename) {
260 if (LLVMPrintModuleToFile(module_ref, filename, error_message)) {270 if (LLVMPrintModuleToFile(module_ref, llvm_ir_filename, error_message)) {
261 return true;271 return true;
272 }
262 }273 }
263 }
264274
265 if (time_report) {275 if (time_report) {
266 TimerGroup::printAll(errs());276 TimerGroup::printAll(errs());
277 }
278
279 // MPM goes out of scope and writes to the out streams
267 }280 }
281
282 delete dest_asm;
283 delete dest_bin;
284
268 return false;285 return false;
269}286}
270287
src/zig_llvm.h+3-10
...@@ -46,17 +46,10 @@ ZIG_EXTERN_C void ZigLLVMInitializeLowerIntrinsicsPass(LLVMPassRegistryRef R);...@@ -46,17 +46,10 @@ ZIG_EXTERN_C void ZigLLVMInitializeLowerIntrinsicsPass(LLVMPassRegistryRef R);
46ZIG_EXTERN_C char *ZigLLVMGetHostCPUName(void);46ZIG_EXTERN_C char *ZigLLVMGetHostCPUName(void);
47ZIG_EXTERN_C char *ZigLLVMGetNativeFeatures(void);47ZIG_EXTERN_C char *ZigLLVMGetNativeFeatures(void);
4848
49// We use a custom enum here since LLVM does not expose LLVMIr as an emit
50// output through the same mechanism as assembly/binary.
51enum ZigLLVM_EmitOutputType {
52 ZigLLVM_EmitAssembly,
53 ZigLLVM_EmitBinary,
54 ZigLLVM_EmitLLVMIr,
55};
56
57ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,49ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,
58 const char *filename, enum ZigLLVM_EmitOutputType output_type, char **error_message, bool is_debug,50 char **error_message, bool is_debug,
59 bool is_small, bool time_report);51 bool is_small, bool time_report,
52 const char *asm_filename, const char *bin_filename, const char *llvm_ir_filename);
6053
61ZIG_EXTERN_C LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Triple,54ZIG_EXTERN_C LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Triple,
62 const char *CPU, const char *Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc,55 const char *CPU, const char *Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc,