mirror of
https://github.com/ziglang/zig.git
synced 2025-12-10 08:13:07 +00:00
* std.cache_hash exposes Hasher type * std.cache_hash makes hasher_init a global const * std.cache_hash supports cloning so that clones can share the same open manifest dir handle as well as fork from shared hasher state * start to populate the cache_hash for stage2 builds * remove a footgun from std.cache_hash add function * get rid of std.Target.ObjectFormat.unknown * rework stage2 logic for resolving output artifact names by adding object_format as an optional parameter to std.zig.binNameAlloc * support -Denable-llvm in stage2 tests * Module supports the use case when there are no .zig files * introduce c_object_table and failed_c_objects to Module * propagate many new kinds of data from CLI into Module and into linker.Options * introduce -fLLVM, -fLLD, -fClang and their -fno- counterparts. closes #6251. - add logic for choosing when to use LLD or zig's self-hosted linker * stub code for implementing invoking Clang to build C objects * add -femit-h, -femit-h=foo, and -fno-emit-h CLI options
105 lines
3.0 KiB
Zig
105 lines
3.0 KiB
Zig
const std = @import("std");
|
|
const mem = std.mem;
|
|
const assert = std.debug.assert;
|
|
const Allocator = std.mem.Allocator;
|
|
const Module = @import("../Module.zig");
|
|
const fs = std.fs;
|
|
const codegen = @import("../codegen/c.zig");
|
|
const link = @import("../link.zig");
|
|
const File = link.File;
|
|
const C = @This();
|
|
|
|
pub const base_tag: File.Tag = .c;
|
|
|
|
base: File,
|
|
|
|
header: std.ArrayList(u8),
|
|
constants: std.ArrayList(u8),
|
|
main: std.ArrayList(u8),
|
|
|
|
called: std.StringHashMap(void),
|
|
need_stddef: bool = false,
|
|
need_stdint: bool = false,
|
|
error_msg: *Module.ErrorMsg = undefined,
|
|
|
|
pub fn openPath(allocator: *Allocator, dir: fs.Dir, sub_path: []const u8, options: link.Options) !*File {
|
|
assert(options.object_format == .c);
|
|
|
|
if (options.use_llvm) return error.LLVM_HasNoCBackend;
|
|
if (options.use_lld) return error.LLD_HasNoCBackend;
|
|
|
|
const file = try dir.createFile(sub_path, .{ .truncate = true, .read = true, .mode = link.determineMode(options) });
|
|
errdefer file.close();
|
|
|
|
var c_file = try allocator.create(C);
|
|
errdefer allocator.destroy(c_file);
|
|
|
|
c_file.* = C{
|
|
.base = .{
|
|
.tag = .c,
|
|
.options = options,
|
|
.file = file,
|
|
.allocator = allocator,
|
|
},
|
|
.main = std.ArrayList(u8).init(allocator),
|
|
.header = std.ArrayList(u8).init(allocator),
|
|
.constants = std.ArrayList(u8).init(allocator),
|
|
.called = std.StringHashMap(void).init(allocator),
|
|
};
|
|
|
|
return &c_file.base;
|
|
}
|
|
|
|
pub fn fail(self: *C, src: usize, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {
|
|
self.error_msg = try Module.ErrorMsg.create(self.base.allocator, src, format, args);
|
|
return error.AnalysisFail;
|
|
}
|
|
|
|
pub fn deinit(self: *C) void {
|
|
self.main.deinit();
|
|
self.header.deinit();
|
|
self.constants.deinit();
|
|
self.called.deinit();
|
|
}
|
|
|
|
pub fn updateDecl(self: *C, module: *Module, decl: *Module.Decl) !void {
|
|
codegen.generate(self, decl) catch |err| {
|
|
if (err == error.AnalysisFail) {
|
|
try module.failed_decls.put(module.gpa, decl, self.error_msg);
|
|
}
|
|
return err;
|
|
};
|
|
}
|
|
|
|
pub fn flush(self: *C, module: *Module) !void {
|
|
const writer = self.base.file.?.writer();
|
|
try writer.writeAll(@embedFile("cbe.h"));
|
|
var includes = false;
|
|
if (self.need_stddef) {
|
|
try writer.writeAll("#include <stddef.h>\n");
|
|
includes = true;
|
|
}
|
|
if (self.need_stdint) {
|
|
try writer.writeAll("#include <stdint.h>\n");
|
|
includes = true;
|
|
}
|
|
if (includes) {
|
|
try writer.writeByte('\n');
|
|
}
|
|
if (self.header.items.len > 0) {
|
|
try writer.print("{}\n", .{self.header.items});
|
|
}
|
|
if (self.constants.items.len > 0) {
|
|
try writer.print("{}\n", .{self.constants.items});
|
|
}
|
|
if (self.main.items.len > 1) {
|
|
const last_two = self.main.items[self.main.items.len - 2 ..];
|
|
if (std.mem.eql(u8, last_two, "\n\n")) {
|
|
self.main.items.len -= 1;
|
|
}
|
|
}
|
|
try writer.writeAll(self.main.items);
|
|
self.base.file.?.close();
|
|
self.base.file = null;
|
|
}
|