From fef94da958c92e59ad277b6934a337b6fb45396c Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Thu, 25 May 2023 12:30:02 +0300 Subject: add compiler flag for selecting C frontend --- src/Compilation.zig | 89 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 50 insertions(+), 39 deletions(-) (limited to 'src/Compilation.zig') diff --git a/src/Compilation.zig b/src/Compilation.zig index 71dff4a442..92d1fb1c40 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -32,7 +32,6 @@ const Module = @import("Module.zig"); const InternPool = @import("InternPool.zig"); const BuildId = std.Build.CompileStep.BuildId; const Cache = std.Build.Cache; -const translate_c = @import("translate_c.zig"); const c_codegen = @import("codegen/c.zig"); const libtsan = @import("libtsan.zig"); const Zir = @import("Zir.zig"); @@ -88,7 +87,7 @@ failed_win32_resources: if (build_options.only_core_functionality) void else std misc_failures: std.AutoArrayHashMapUnmanaged(MiscTask, MiscError) = .{}, keep_source_files_loaded: bool, -use_clang: bool, +c_frontend: CFrontend, sanitize_c: bool, /// When this is `true` it means invoking clang as a sub-process is expected to inherit /// stdin, stdout, stderr, and if it returns non success, to forward the exit code. @@ -515,6 +514,8 @@ pub const cache_helpers = struct { } }; +pub const CFrontend = enum { clang, aro }; + pub const ClangPreprocessorMode = enum { no, /// This means we are doing `zig cc -E -o `. @@ -1046,14 +1047,11 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { break :pic explicit; } else pie or must_pic; - // Make a decision on whether to use Clang for translate-c and compiling C files. - const use_clang = if (options.use_clang) |explicit| explicit else blk: { - if (build_options.have_llvm) { - // Can't use it if we don't have it! - break :blk false; - } - // It's not planned to do our own translate-c or C compilation. - break :blk true; + // Make a decision on whether to use Clang or Aro for translate-c and compiling C files. + const c_frontend: CFrontend = blk: { + if (!build_options.have_llvm) break :blk .aro; + if (options.use_clang) |explicit| if (explicit) break :blk .clang; + break :blk .clang; }; const is_safe_mode = switch (options.optimize_mode) { @@ -1677,7 +1675,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { .astgen_work_queue = std.fifo.LinearFifo(*Module.File, .Dynamic).init(gpa), .embed_file_work_queue = std.fifo.LinearFifo(*Module.EmbedFile, .Dynamic).init(gpa), .keep_source_files_loaded = options.keep_source_files_loaded, - .use_clang = use_clang, + .c_frontend = c_frontend, .clang_argv = options.clang_argv, .c_source_files = options.c_source_files, .rc_source_files = options.rc_source_files, @@ -3918,9 +3916,7 @@ pub const CImportResult = struct { /// This API is currently coupled pretty tightly to stage1's needs; it will need to be reworked /// a bit when we want to start using it from self-hosted. pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult { - if (!build_options.have_llvm) - return error.ZigCompilerNotBuiltWithLLVMExtensions; - + if (build_options.only_c) unreachable; // @cImport is not needed for bootstrapping const tracy_trace = trace(@src()); defer tracy_trace.end(); @@ -3967,7 +3963,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult { var argv = std.ArrayList([]const u8).init(comp.gpa); defer argv.deinit(); - try argv.append(""); // argv[0] is program name, actual args start at [1] + try argv.append(@tagName(comp.c_frontend)); // argv[0] is program name, actual args start at [1] try comp.addTranslateCCArgs(arena, &argv, .c, out_dep_path); try argv.append(out_h_path); @@ -3975,31 +3971,43 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult { if (comp.verbose_cc) { dump_argv(argv.items); } + var tree = switch (comp.c_frontend) { + .aro => tree: { + if (builtin.zig_backend == .stage2_c) @panic("the CBE cannot compile Aro yet!"); + const translate_c = @import("aro_translate_c.zig"); + _ = translate_c; + break :tree undefined; + }, + .clang => tree: { + if (!build_options.have_llvm) unreachable; + const translate_c = @import("translate_c.zig"); + + // Convert to null terminated args. + const new_argv_with_sentinel = try arena.alloc(?[*:0]const u8, argv.items.len + 1); + new_argv_with_sentinel[argv.items.len] = null; + const new_argv = new_argv_with_sentinel[0..argv.items.len :null]; + for (argv.items, 0..) |arg, i| { + new_argv[i] = try arena.dupeZ(u8, arg); + } - // Convert to null terminated args. - const new_argv_with_sentinel = try arena.alloc(?[*:0]const u8, argv.items.len + 1); - new_argv_with_sentinel[argv.items.len] = null; - const new_argv = new_argv_with_sentinel[0..argv.items.len :null]; - for (argv.items, 0..) |arg, i| { - new_argv[i] = try arena.dupeZ(u8, arg); - } - - const c_headers_dir_path_z = try comp.zig_lib_directory.joinZ(arena, &[_][]const u8{"include"}); - var errors = std.zig.ErrorBundle.empty; - errdefer errors.deinit(comp.gpa); - var tree = translate_c.translate( - comp.gpa, - new_argv.ptr, - new_argv.ptr + new_argv.len, - &errors, - c_headers_dir_path_z, - ) catch |err| switch (err) { - error.OutOfMemory => return error.OutOfMemory, - error.SemanticAnalyzeFail => { - return CImportResult{ - .out_zig_path = "", - .cache_hit = actual_hit, - .errors = errors, + const c_headers_dir_path_z = try comp.zig_lib_directory.joinZ(arena, &[_][]const u8{"include"}); + var errors = std.zig.ErrorBundle.empty; + errdefer errors.deinit(comp.gpa); + break :tree translate_c.translate( + comp.gpa, + new_argv.ptr, + new_argv.ptr + new_argv.len, + &errors, + c_headers_dir_path_z, + ) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.SemanticAnalyzeFail => { + return CImportResult{ + .out_zig_path = "", + .cache_hit = actual_hit, + .errors = errors, + }; + }, }; }, }; @@ -4249,6 +4257,9 @@ fn reportRetryableEmbedFileError( } fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.Progress.Node) !void { + if (comp.c_frontend == .aro) { + return comp.failCObj(c_object, "aro does not support compiling C objects yet", .{}); + } if (!build_options.have_llvm) { return comp.failCObj(c_object, "clang not available: compiler built without LLVM extensions", .{}); } -- cgit v1.2.3