Commit e7a622fb33
Changed files (24)
lib
src
libs
lib/compiler/aro/aro/Parser/Diagnostic.zig
@@ -694,6 +694,12 @@ pub const invalid_cast_type: Diagnostic = .{
.kind = .@"error",
};
+pub const cast_to_same_type: Diagnostic = .{
+ .fmt = "C99 forbids casting nonscalar type {qt} to the same type",
+ .kind = .off,
+ .extension = true,
+};
+
pub const invalid_cast_operand_type: Diagnostic = .{
.fmt = "operand of type {qt} where arithmetic or pointer type is required",
.kind = .@"error",
@@ -1484,9 +1490,10 @@ pub const duplicate_member: Diagnostic = .{
};
pub const binary_integer_literal: Diagnostic = .{
- .fmt = "binary integer literals are a GNU extension",
+ .fmt = "binary integer literals are a C23 extension",
+ .opt = .@"c23-extensions",
.kind = .off,
- .opt = .@"gnu-binary-literal",
+ .suppress_version = .c23,
.extension = true,
};
lib/compiler/aro/aro/Compilation.zig
@@ -10,6 +10,7 @@ const CodeGenOptions = @import("../backend.zig").CodeGenOptions;
const Builtins = @import("Builtins.zig");
const Builtin = Builtins.Builtin;
const Diagnostics = @import("Diagnostics.zig");
+const DepFile = @import("DepFile.zig");
const LangOpts = @import("LangOpts.zig");
const Pragma = @import("Pragma.zig");
const record_layout = @import("record_layout.zig");
@@ -140,6 +141,7 @@ system_framework_dirs: std.ArrayListUnmanaged([]const u8) = .empty,
/// Allocated into `gpa`, but keys are externally managed.
embed_dirs: std.ArrayListUnmanaged([]const u8) = .empty,
target: std.Target = @import("builtin").target,
+cmodel: std.builtin.CodeModel = .default,
pragma_handlers: std.StringArrayHashMapUnmanaged(*Pragma) = .{},
langopts: LangOpts = .{},
generated_buf: std.ArrayListUnmanaged(u8) = .{},
@@ -349,30 +351,206 @@ fn generateSystemDefines(comp: *Compilation, w: *std.Io.Writer) !void {
// architecture macros
switch (comp.target.cpu.arch) {
- .x86_64 => {
- try define(w, "__amd64__");
- try define(w, "__amd64");
- try define(w, "__x86_64__");
- try define(w, "__x86_64");
+ .x86, .x86_64 => {
+ try w.print("#define __code_model_{s}__ 1\n", .{switch (comp.cmodel) {
+ .default => "small",
+ else => @tagName(comp.cmodel),
+ }});
+
+ if (comp.target.cpu.arch == .x86_64) {
+ try define(w, "__amd64__");
+ try define(w, "__amd64");
+ try define(w, "__x86_64__");
+ try define(w, "__x86_64");
+
+ if (comp.target.os.tag == .windows and comp.target.abi == .msvc) {
+ try w.writeAll(
+ \\#define _M_X64 100
+ \\#define _M_AMD64 100
+ \\
+ );
+ }
+ } else {
+ try defineStd(w, "i386", is_gnu);
+
+ if (comp.target.os.tag == .windows and comp.target.abi == .msvc) {
+ try w.print("#define _M_IX86 {d}\n", .{blk: {
+ if (comp.target.cpu.model == &std.Target.x86.cpu.i386) break :blk 300;
+ if (comp.target.cpu.model == &std.Target.x86.cpu.i486) break :blk 400;
+ if (comp.target.cpu.model == &std.Target.x86.cpu.i586) break :blk 500;
+ break :blk @as(u32, 600);
+ }});
+ }
+ }
+ try define(w, "__SEG_GS");
+ try define(w, "__SEG_FS");
+ try w.writeAll(
+ \\#define __seg_gs __attribute__((address_space(256)))
+ \\#define __seg_fs __attribute__((address_space(257)))
+ \\
+ );
- if (comp.target.os.tag == .windows and comp.target.abi == .msvc) {
- try w.writeAll(
- \\#define _M_X64 100
- \\#define _M_AMD64 100
- \\
- );
+ if (comp.target.cpu.has(.x86, .sahf) or (comp.langopts.emulate == .clang and comp.target.cpu.arch == .x86)) {
+ try define(w, "__LAHF_SAHF__");
}
- },
- .x86 => {
- try defineStd(w, "i386", is_gnu);
- if (comp.target.os.tag == .windows and comp.target.abi == .msvc) {
- try w.print("#define _M_IX86 {d}\n", .{blk: {
- if (comp.target.cpu.model == &std.Target.x86.cpu.i386) break :blk 300;
- if (comp.target.cpu.model == &std.Target.x86.cpu.i486) break :blk 400;
- if (comp.target.cpu.model == &std.Target.x86.cpu.i586) break :blk 500;
- break :blk @as(u32, 600);
- }});
+ const features = comp.target.cpu.features;
+ for ([_]struct { std.Target.x86.Feature, []const u8 }{
+ .{ .aes, "__AES__" },
+ .{ .vaes, "__VAES__" },
+ .{ .pclmul, "__PCLMUL__" },
+ .{ .vpclmulqdq, "__VPCLMULQDQ__" },
+ .{ .lzcnt, "__LZCNT__" },
+ .{ .rdrnd, "__RDRND__" },
+ .{ .fsgsbase, "__FSGSBASE__" },
+ .{ .bmi, "__BMI__" },
+ .{ .bmi2, "__BMI2__" },
+ .{ .popcnt, "__POPCNT__" },
+ .{ .rtm, "__RTM__" },
+ .{ .prfchw, "__PRFCHW__" },
+ .{ .rdseed, "__RDSEED__" },
+ .{ .adx, "__ADX__" },
+ .{ .tbm, "__TBM__" },
+ .{ .lwp, "__LWP__" },
+ .{ .mwaitx, "__MWAITX__" },
+ .{ .movbe, "__MOVBE__" },
+
+ .{ .xop, "__XOP__" },
+ .{ .fma4, "__FMA4__" },
+ .{ .sse4a, "__SSE4A__" },
+
+ .{ .fma, "__FMA__" },
+ .{ .f16c, "__F16C__" },
+ .{ .gfni, "__GFNI__" },
+ .{ .evex512, "__EVEX512__" },
+ .{ .avx10_1_256, "__AVX10_1__" },
+ .{ .avx10_1_512, "__AVX10_1_512__" },
+ .{ .avx10_2_256, "__AVX10_2__" },
+ .{ .avx10_2_512, "__AVX10_2_512__" },
+ .{ .avx512cd, "__AVX512CD__" },
+ .{ .avx512vpopcntdq, "__AVX512VPOPCNTDQ__" },
+ .{ .avx512vnni, "__AVX512VNNI__" },
+ .{ .avx512bf16, "__AVX512BF16__" },
+ .{ .avx512fp16, "__AVX512FP16__" },
+ .{ .avx512dq, "__AVX512DQ__" },
+ .{ .avx512bitalg, "__AVX512BITALG__" },
+ .{ .avx512bw, "__AVX512BW__" },
+
+ .{ .avx512vl, "__AVX512VL__" },
+ .{ .avx512vl, "__EVEX256__" },
+
+ .{ .avx512vbmi, "__AVX512VBMI__" },
+ .{ .avx512vbmi2, "__AVX512VBMI2__" },
+ .{ .avx512ifma, "__AVX512IFMA__" },
+ .{ .avx512vp2intersect, "__AVX512VP2INTERSECT__" },
+ .{ .sha, "__SHA__" },
+ .{ .sha512, "__SHA512__" },
+ .{ .fxsr, "__FXSR__" },
+ .{ .xsave, "__XSAVE__" },
+ .{ .xsaveopt, "__XSAVEOPT__" },
+ .{ .xsavec, "__XSAVEC__" },
+ .{ .xsaves, "__XSAVES__" },
+ .{ .pku, "__PKU__" },
+ .{ .clflushopt, "__CLFLUSHOPT__" },
+ .{ .clwb, "__CLWB__" },
+ .{ .wbnoinvd, "__WBNOINVD__" },
+ .{ .shstk, "__SHSTK__" },
+ .{ .sgx, "__SGX__" },
+ .{ .sm3, "__SM3__" },
+ .{ .sm4, "__SM4__" },
+ .{ .prefetchi, "__PREFETCHI__" },
+ .{ .clzero, "__CLZERO__" },
+ .{ .kl, "__KL__" },
+ .{ .widekl, "__WIDEKL__" },
+ .{ .rdpid, "__RDPID__" },
+ .{ .rdpru, "__RDPRU__" },
+ .{ .cldemote, "__CLDEMOTE__" },
+ .{ .waitpkg, "__WAITPKG__" },
+ .{ .movdiri, "__MOVDIRI__" },
+ .{ .movdir64b, "__MOVDIR64B__" },
+ .{ .movrs, "__MOVRS__" },
+ .{ .pconfig, "__PCONFIG__" },
+ .{ .ptwrite, "__PTWRITE__" },
+ .{ .invpcid, "__INVPCID__" },
+ .{ .enqcmd, "__ENQCMD__" },
+ .{ .hreset, "__HRESET__" },
+ .{ .amx_tile, "__AMX_TILE__" },
+ .{ .amx_int8, "__AMX_INT8__" },
+ .{ .amx_bf16, "__AMX_BF16__" },
+ .{ .amx_fp16, "__AMX_FP16__" },
+ .{ .amx_complex, "__AMX_COMPLEX__" },
+ .{ .amx_fp8, "__AMX_FP8__" },
+ .{ .amx_movrs, "__AMX_MOVRS__" },
+ .{ .amx_transpose, "__AMX_TRANSPOSE__" },
+ .{ .amx_avx512, "__AMX_AVX512__" },
+ .{ .amx_tf32, "__AMX_TF32__" },
+ .{ .cmpccxadd, "__CMPCCXADD__" },
+ .{ .raoint, "__RAOINT__" },
+ .{ .avxifma, "__AVXIFMA__" },
+ .{ .avxneconvert, "__AVXNECONVERT__" },
+ .{ .avxvnni, "__AVXVNNI__" },
+ .{ .avxvnniint16, "__AVXVNNIINT16__" },
+ .{ .avxvnniint8, "__AVXVNNIINT8__" },
+ .{ .serialize, "__SERIALIZE__" },
+ .{ .tsxldtrk, "__TSXLDTRK__" },
+ .{ .uintr, "__UINTR__" },
+ .{ .usermsr, "__USERMSR__" },
+ .{ .crc32, "__CRC32__" },
+ .{ .egpr, "__EGPR__" },
+ .{ .push2pop2, "__PUSH2POP2__" },
+ .{ .ppx, "__PPX__" },
+ .{ .ndd, "__NDD__" },
+ .{ .ccmp, "__CCMP__" },
+ .{ .nf, "__NF__" },
+ .{ .cf, "__CF__" },
+ .{ .zu, "__ZU__" },
+
+ .{ .avx512f, "__AVX512F__" },
+ .{ .avx2, "__AVX2__" },
+ .{ .avx, "__AVX__" },
+ .{ .sse4_2, "__SSE4_2__" },
+ .{ .sse4_1, "__SSE4_1__" },
+ .{ .ssse3, "__SSSE3__" },
+ .{ .sse3, "__SSE3__" },
+ .{ .sse2, "__SSE2__" },
+ .{ .sse, "__SSE__" },
+ .{ .sse, "__SSE_MATH__" },
+
+ .{ .mmx, "__MMX__" },
+ }) |fs| {
+ if (features.isEnabled(@intFromEnum(fs[0]))) {
+ try define(w, fs[1]);
+ }
+ }
+
+ if (comp.langopts.ms_extensions and comp.target.cpu.arch == .x86) {
+ const level = if (comp.target.cpu.has(.x86, .sse2))
+ "2"
+ else if (comp.target.cpu.has(.x86, .sse))
+ "1"
+ else
+ "0";
+
+ try w.print("#define _M_IX86_FP {s}\n", .{level});
+ }
+
+ if (comp.target.cpu.hasAll(.x86, &.{ .egpr, .push2pop2, .ppx, .ndd, .ccmp, .nf, .cf, .zu })) {
+ try define(w, "__APX_F__");
+ }
+
+ if (comp.target.cpu.hasAll(.x86, &.{ .egpr, .inline_asm_use_gpr32 })) {
+ try define(w, "__APX_INLINE_ASM_USE_GPR32__");
+ }
+
+ if (comp.target.cpu.has(.x86, .cx8)) {
+ try define(w, "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
+ }
+ if (comp.target.cpu.has(.x86, .cx16) and comp.target.cpu.arch == .x86_64) {
+ try define(w, "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
+ }
+
+ if (comp.hasFloat128()) {
+ try w.writeAll("#define __SIZEOF_FLOAT128__ 16\n");
}
},
.mips,
@@ -443,13 +621,132 @@ fn generateSystemDefines(comp: *Compilation, w: *std.Io.Writer) !void {
try define(w, "__arm64__");
}
if (comp.target.os.tag == .windows and comp.target.abi == .msvc) {
- try w.writeAll("#define _M_ARM64 100\n");
+ try w.writeAll("#define _M_ARM64 1\n");
+ }
+
+ {
+ const cmodel = switch (comp.cmodel) {
+ .default => "small",
+ else => @tagName(comp.cmodel),
+ };
+ try w.writeAll("#define __AARCH64_CMODEL_");
+ for (cmodel) |c| {
+ try w.writeByte(std.ascii.toUpper(c));
+ }
+ try w.writeAll("__ 1\n");
+ }
+
+ if (comp.target.cpu.has(.aarch64, .fp_armv8)) {
+ try w.writeAll("#define __ARM_FP 0xE\n");
+ }
+ if (comp.target.cpu.has(.aarch64, .neon)) {
+ try define(w, "__ARM_NEON");
+ try w.writeAll("#define __ARM_NEON_FP 0xE\n");
+ }
+ if (comp.target.cpu.has(.aarch64, .bf16)) {
+ try define(w, "__ARM_FEATURE_BF16");
+ try define(w, "__ARM_FEATURE_BF16_VECTOR_ARITHMETIC");
+ try define(w, "__ARM_BF16_FORMAT_ALTERNATIVE");
+ try define(w, "__ARM_FEATURE_BF16_SCALAR_ARITHMETIC");
+ if (comp.target.cpu.has(.aarch64, .sve)) {
+ try define(w, "__ARM_FEATURE_SVE_BF16");
+ }
+ }
+ if (comp.target.cpu.hasAll(.aarch64, &.{ .sve2, .sve_aes })) {
+ try define(w, "__ARM_FEATURE_SVE2_AES");
+ }
+ if (comp.target.cpu.hasAll(.aarch64, &.{ .sve2, .sve_bitperm })) {
+ try define(w, "__ARM_FEATURE_SVE2_BITPERM");
+ }
+ if (comp.target.cpu.has(.aarch64, .sme)) {
+ try define(w, "__ARM_FEATURE_SME");
+ try define(w, "__ARM_FEATURE_LOCALLY_STREAMING");
+ }
+ if (comp.target.cpu.has(.aarch64, .fmv)) {
+ try define(w, "__HAVE_FUNCTION_MULTI_VERSIONING");
+ }
+ if (comp.target.cpu.has(.aarch64, .sha3)) {
+ try define(w, "__ARM_FEATURE_SHA3");
+ try define(w, "__ARM_FEATURE_SHA512");
+ }
+ if (comp.target.cpu.has(.aarch64, .sm4)) {
+ try define(w, "__ARM_FEATURE_SM3");
+ try define(w, "__ARM_FEATURE_SM4");
+ }
+ if (!comp.target.cpu.has(.aarch64, .strict_align)) {
+ try define(w, "__ARM_FEATURE_UNALIGNED");
+ }
+ if (comp.target.cpu.hasAll(.aarch64, &.{ .neon, .fullfp16 })) {
+ try define(w, "__ARM_FEATURE_FP16_VECTOR_ARITHMETIC");
+ }
+ if (comp.target.cpu.has(.aarch64, .rcpc3)) {
+ try w.writeAll("#define __ARM_FEATURE_RCPC 3\n");
+ } else if (comp.target.cpu.has(.aarch64, .rcpc)) {
+ try define(w, "__ARM_FEATURE_RCPC");
+ }
+
+ const features = comp.target.cpu.features;
+ for ([_]struct { std.Target.aarch64.Feature, []const u8 }{
+ .{ .sve, "SVE" },
+ .{ .sve2, "SVE2" },
+ .{ .sve2p1, "SVE2p1" },
+ .{ .sve2_sha3, "SVE2_SHA3" },
+ .{ .sve2_sm4, "SVE2_SM4" },
+ .{ .sve_b16b16, "SVE_B16B16" },
+ .{ .sme2, "SME2" },
+ .{ .sme2p1, "SME2p1" },
+ .{ .sme_f16f16, "SME_F16F16" },
+ .{ .sme_b16b16, "SME_B16B16" },
+ .{ .crc, "CRC32" },
+ .{ .aes, "AES" },
+ .{ .sha2, "SHA2" },
+ .{ .pauth, "PAUTH" },
+ .{ .pauth_lr, "PAUTH_LR" },
+ .{ .bti, "BTI" },
+ .{ .fullfp16, "FP16_SCALAR_ARITHMETIC" },
+ .{ .dotprod, "DOTPROD" },
+ .{ .mte, "MEMORY_TAGGING" },
+ .{ .tme, "TME" },
+ .{ .i8mm, "MATMUL_INT8" },
+ .{ .lse, "ATOMICS" },
+ .{ .f64mm, "SVE_MATMUL_FP64" },
+ .{ .f32mm, "SVE_MATMUL_FP32" },
+ .{ .i8mm, "SVE_MATMUL_INT8" },
+ .{ .fp16fml, "FP16_FML" },
+ .{ .ls64, "LS64" },
+ .{ .rand, "RNG" },
+ .{ .mops, "MOPS" },
+ .{ .d128, "SYSREG128" },
+ .{ .gcs, "GCS" },
+ }) |fs| {
+ if (features.isEnabled(@intFromEnum(fs[0]))) {
+ try w.print("#define __ARM_FEATURE_{s} 1\n", .{fs[1]});
+ }
}
},
.msp430 => {
try define(w, "MSP430");
try define(w, "__MSP430__");
},
+ .arc => {
+ try define(w, "__arc__");
+ },
+ .wasm32, .wasm64 => {
+ try define(w, "__wasm");
+ try define(w, "__wasm__");
+ if (comp.target.cpu.arch == .wasm32) {
+ try define(w, "__wasm32");
+ try define(w, "__wasm32__");
+ } else {
+ try define(w, "__wasm64");
+ try define(w, "__wasm64__");
+ }
+
+ for (comp.target.cpu.arch.allFeaturesList()) |feature| {
+ if (!comp.target.cpu.features.isEnabled(feature.index)) continue;
+ try w.print("#define __wasm_{s}__ 1\n", .{feature.name});
+ }
+ },
else => {},
}
@@ -1477,7 +1774,7 @@ fn getFileContents(comp: *Compilation, path: []const u8, limit: std.Io.Limit) ![
var file_buf: [4096]u8 = undefined;
var file_reader = file.reader(&file_buf);
- if (limit.minInt(try file_reader.getSize()) > std.math.maxInt(u32)) return error.FileTooBig;
+ if (limit.minInt64(try file_reader.getSize()) > std.math.maxInt(u32)) return error.FileTooBig;
_ = allocating.writer.sendFileAll(&file_reader, limit) catch |err| switch (err) {
error.WriteFailed => return error.OutOfMemory,
@@ -1494,14 +1791,16 @@ pub fn findEmbed(
/// angle bracket vs quotes
include_type: IncludeType,
limit: std.Io.Limit,
+ opt_dep_file: ?*DepFile,
) !?[]const u8 {
if (std.fs.path.isAbsolute(filename)) {
- return if (comp.getFileContents(filename, limit)) |some|
- some
- else |err| switch (err) {
+ if (comp.getFileContents(filename, limit)) |some| {
+ if (opt_dep_file) |dep_file| try dep_file.addDependencyDupe(comp.gpa, comp.arena, filename);
+ return some;
+ } else |err| switch (err) {
error.OutOfMemory => |e| return e,
- else => null,
- };
+ else => return null,
+ }
}
var stack_fallback = std.heap.stackFallback(path_buf_stack_limit, comp.gpa);
@@ -1516,6 +1815,7 @@ pub fn findEmbed(
std.mem.replaceScalar(u8, path, '\\', '/');
}
if (comp.getFileContents(path, limit)) |some| {
+ if (opt_dep_file) |dep_file| try dep_file.addDependencyDupe(comp.gpa, comp.arena, filename);
return some;
} else |err| switch (err) {
error.OutOfMemory => return error.OutOfMemory,
@@ -1531,6 +1831,7 @@ pub fn findEmbed(
std.mem.replaceScalar(u8, path, '\\', '/');
}
if (comp.getFileContents(path, limit)) |some| {
+ if (opt_dep_file) |dep_file| try dep_file.addDependencyDupe(comp.gpa, comp.arena, filename);
return some;
} else |err| switch (err) {
error.OutOfMemory => return error.OutOfMemory,
lib/compiler/aro/aro/DepFile.zig
@@ -0,0 +1,78 @@
+const std = @import("std");
+const Allocator = std.mem.Allocator;
+
+pub const Format = enum { make, nmake };
+
+const DepFile = @This();
+
+target: []const u8,
+deps: std.StringArrayHashMapUnmanaged(void) = .empty,
+format: Format,
+
+pub fn deinit(d: *DepFile, gpa: Allocator) void {
+ d.deps.deinit(gpa);
+ d.* = undefined;
+}
+
+pub fn addDependency(d: *DepFile, gpa: Allocator, path: []const u8) !void {
+ try d.deps.put(gpa, path, {});
+}
+
+pub fn addDependencyDupe(d: *DepFile, gpa: Allocator, arena: Allocator, path: []const u8) !void {
+ const gop = try d.deps.getOrPut(gpa, path);
+ if (gop.found_existing) return;
+ gop.key_ptr.* = try arena.dupe(u8, path);
+}
+
+pub fn write(d: *const DepFile, w: *std.Io.Writer) std.Io.Writer.Error!void {
+ const max_columns = 75;
+ var columns: usize = 0;
+
+ try w.writeAll(d.target);
+ columns += d.target.len;
+ try w.writeByte(':');
+ columns += 1;
+
+ for (d.deps.keys()) |path| {
+ if (std.mem.eql(u8, path, "<stdin>")) continue;
+
+ if (columns + path.len + " \\\n".len > max_columns) {
+ try w.writeAll(" \\\n ");
+ columns = 1;
+ }
+ try w.writeByte(' ');
+ try d.writePath(path, w);
+ columns += path.len + 1;
+ }
+ try w.writeByte('\n');
+ try w.flush();
+}
+
+fn writePath(d: *const DepFile, path: []const u8, w: *std.Io.Writer) !void {
+ switch (d.format) {
+ .nmake => {
+ if (std.mem.indexOfAny(u8, path, " #${}^!")) |_|
+ try w.print("\"{s}\"", .{path})
+ else
+ try w.writeAll(path);
+ },
+ .make => {
+ for (path, 0..) |c, i| {
+ if (c == '#') {
+ try w.writeByte('\\');
+ } else if (c == '$') {
+ try w.writeByte('$');
+ } else if (c == ' ') {
+ try w.writeByte('\\');
+ var j = i;
+ while (j != 0) {
+ j -= 1;
+ if (path[j] != '\\') break;
+ try w.writeByte('\\');
+ }
+ }
+ try w.writeByte(c);
+ }
+ },
+ }
+}
lib/compiler/aro/aro/Diagnostics.zig
@@ -23,6 +23,52 @@ pub const Message = struct {
@"error",
@"fatal error",
};
+
+ pub fn write(msg: Message, w: *std.Io.Writer, config: std.Io.tty.Config, details: bool) std.Io.tty.Config.SetColorError!void {
+ try config.setColor(w, .bold);
+ if (msg.location) |loc| {
+ try w.print("{s}:{d}:{d}: ", .{ loc.path, loc.line_no, loc.col });
+ }
+ switch (msg.effective_kind) {
+ .@"fatal error", .@"error" => try config.setColor(w, .bright_red),
+ .note => try config.setColor(w, .bright_cyan),
+ .warning => try config.setColor(w, .bright_magenta),
+ .off => unreachable,
+ }
+ try w.print("{s}: ", .{@tagName(msg.effective_kind)});
+
+ try config.setColor(w, .white);
+ try w.writeAll(msg.text);
+ if (msg.opt) |some| {
+ if (msg.effective_kind == .@"error" and msg.kind != .@"error") {
+ try w.print(" [-Werror,-W{s}]", .{@tagName(some)});
+ } else if (msg.effective_kind != .note) {
+ try w.print(" [-W{s}]", .{@tagName(some)});
+ }
+ } else if (msg.extension) {
+ if (msg.effective_kind == .@"error") {
+ try w.writeAll(" [-Werror,-Wpedantic]");
+ } else if (msg.effective_kind != msg.kind) {
+ try w.writeAll(" [-Wpedantic]");
+ }
+ }
+
+ if (!details or msg.location == null) {
+ try w.writeAll("\n");
+ try config.setColor(w, .reset);
+ } else {
+ const loc = msg.location.?;
+ const trailer = if (loc.end_with_splice) "\\ " else "";
+ try config.setColor(w, .reset);
+ try w.print("\n{s}{s}\n", .{ loc.line, trailer });
+ try w.splatByteAll(' ', loc.width);
+ try config.setColor(w, .bold);
+ try config.setColor(w, .bright_green);
+ try w.writeAll("^\n");
+ try config.setColor(w, .reset);
+ }
+ try w.flush();
+ }
};
pub const Option = enum {
@@ -247,6 +293,11 @@ output: union(enum) {
},
ignore,
},
+/// Force usage of color in output.
+color: ?bool = null,
+/// Include line of code in output.
+details: bool = true,
+
state: State = .{},
/// Amount of error or fatal error messages that have been sent to `output`.
errors: u32 = 0,
@@ -468,7 +519,10 @@ fn addMessage(d: *Diagnostics, msg: Message) Compilation.Error!void {
switch (d.output) {
.ignore => {},
.to_writer => |writer| {
- writeToWriter(msg, writer.writer, writer.color) catch {
+ var config = writer.color;
+ if (d.color == false) config = .no_color;
+ if (d.color == true and config == .no_color) config = .escape_codes;
+ msg.write(writer.writer, config, d.details) catch {
return error.FatalError;
};
},
@@ -485,48 +539,3 @@ fn addMessage(d: *Diagnostics, msg: Message) Compilation.Error!void {
},
}
}
-
-pub fn writeToWriter(msg: Message, w: *std.Io.Writer, config: std.Io.tty.Config) !void {
- try config.setColor(w, .bold);
- if (msg.location) |loc| {
- try w.print("{s}:{d}:{d}: ", .{ loc.path, loc.line_no, loc.col });
- }
- switch (msg.effective_kind) {
- .@"fatal error", .@"error" => try config.setColor(w, .bright_red),
- .note => try config.setColor(w, .bright_cyan),
- .warning => try config.setColor(w, .bright_magenta),
- .off => unreachable,
- }
- try w.print("{s}: ", .{@tagName(msg.effective_kind)});
-
- try config.setColor(w, .white);
- try w.writeAll(msg.text);
- if (msg.opt) |some| {
- if (msg.effective_kind == .@"error" and msg.kind != .@"error") {
- try w.print(" [-Werror,-W{s}]", .{@tagName(some)});
- } else if (msg.effective_kind != .note) {
- try w.print(" [-W{s}]", .{@tagName(some)});
- }
- } else if (msg.extension) {
- if (msg.effective_kind == .@"error") {
- try w.writeAll(" [-Werror,-Wpedantic]");
- } else if (msg.effective_kind != msg.kind) {
- try w.writeAll(" [-Wpedantic]");
- }
- }
-
- if (msg.location) |loc| {
- const trailer = if (loc.end_with_splice) "\\ " else "";
- try config.setColor(w, .reset);
- try w.print("\n{s}{s}\n", .{ loc.line, trailer });
- try w.splatByteAll(' ', loc.width);
- try config.setColor(w, .bold);
- try config.setColor(w, .bright_green);
- try w.writeAll("^\n");
- try config.setColor(w, .reset);
- } else {
- try w.writeAll("\n");
- try config.setColor(w, .reset);
- }
- try w.flush();
-}
lib/compiler/aro/aro/Driver.zig
@@ -10,6 +10,7 @@ const Object = backend.Object;
const Compilation = @import("Compilation.zig");
const Diagnostics = @import("Diagnostics.zig");
+const DepFile = @import("DepFile.zig");
const GCCVersion = @import("Driver/GCCVersion.zig");
const LangOpts = @import("LangOpts.zig");
const Preprocessor = @import("Preprocessor.zig");
@@ -63,7 +64,6 @@ verbose_ast: bool = false,
verbose_pp: bool = false,
verbose_ir: bool = false,
verbose_linker_args: bool = false,
-color: ?bool = null,
nobuiltininc: bool = false,
nostdinc: bool = false,
nostdlibinc: bool = false,
@@ -73,7 +73,6 @@ mabicalls: ?bool = null,
dynamic_nopic: ?bool = null,
ropi: bool = false,
rwpi: bool = false,
-cmodel: std.builtin.CodeModel = .default,
debug_dump_letters: packed struct(u3) {
d: bool = false,
m: bool = false,
@@ -88,17 +87,27 @@ debug_dump_letters: packed struct(u3) {
return .result_only;
}
} = .{},
+dependencies: struct {
+ m: bool = false,
+ md: bool = false,
+ format: DepFile.Format = .make,
+ file: ?[]const u8 = null,
+} = .{},
/// Full path to the aro executable
aro_name: []const u8 = "",
-/// Value of --triple= passed via CLI
+/// Value of -target passed via CLI
raw_target_triple: ?[]const u8 = null,
+/// Value of -mcpu passed via CLI
+raw_cpu: ?[]const u8 = null,
+
/// Non-optimizing assembly backend is currently selected by passing `-O0`
use_assembly_backend: bool = false,
// linker options
+use_linker: ?[]const u8 = null,
linker_path: ?[]const u8 = null,
nodefaultlibs: bool = false,
nolibc: bool = false,
@@ -133,13 +142,26 @@ pub const usage =
\\ --help Print this message
\\ --version Print aro version
\\
- \\Compile options:
- \\ -c, --compile Only run preprocess, compile, and assemble steps
+ \\Preprocessor options:
+ \\ -C Do not discard comments
+ \\ -CC Do not discard comments, including in macro expansions
\\ -dM Output #define directives for all the macros defined during the execution of the preprocessor
\\ -dD Like -dM except that it outputs both the #define directives and the result of preprocessing
\\ -dN Like -dD, but emit only the macro names, not their expansions.
\\ -D <macro>=<value> Define <macro> to <value> (defaults to 1)
\\ -E Only run the preprocessor
+ \\ -fdollars-in-identifiers
+ \\ Allow '$' in identifiers
+ \\ -fno-dollars-in-identifiers
+ \\ Disallow '$' in identifiers
+ \\ -M Output dependency file instead of preprocessing result
+ \\ -MD Like -M except -E is not implied
+ \\ -MF <file> Write dependency file to <file>
+ \\ -MV Use NMake/Jom format for dependency file
+ \\ -P, --no-line-commands Disable linemarker output in -E mode
+ \\
+ \\Compile options:
+ \\ -c, --compile Only run preprocess, compile, and assemble steps
\\ -fapple-kext Use Apple's kernel extensions ABI
\\ -fchar8_t Enable char8_t (enabled by default in C23 and later)
\\ -fno-char8_t Disable char8_t (disabled by default for pre-C23)
@@ -158,10 +180,6 @@ pub const usage =
\\ -fhosted Compilation in a hosted environment
\\ -fms-extensions Enable support for Microsoft extensions
\\ -fno-ms-extensions Disable support for Microsoft extensions
- \\ -fdollars-in-identifiers
- \\ Allow '$' in identifiers
- \\ -fno-dollars-in-identifiers
- \\ Disallow '$' in identifiers
\\ -g Generate debug information
\\ -fmacro-backtrace-limit=<limit>
\\ Set limit on how many macro expansion traces are shown in errors (default 6)
@@ -197,6 +215,7 @@ pub const usage =
\\ -mabicalls Enable SVR4-style position-independent code (Mips only)
\\ -mno-abicalls Disable SVR4-style position-independent code (Mips only)
\\ -mcmodel=<code-model> Generate code for the given code model
+ \\ -mcpu [cpu] Specify target CPU and feature set
\\ -mkernel Enable kernel development mode
\\ -nobuiltininc Do not search the compiler's builtin directory for include files
\\ -resource-dir <dir> Override the path to the compiler's builtin resource directory
@@ -204,7 +223,6 @@ pub const usage =
\\ Do not search the standard system directories or compiler builtin directories for include files.
\\ -nostdlibinc Do not search the standard system directories for include files, but do search compiler builtin include directories
\\ -o <file> Write output to <file>
- \\ -P, --no-line-commands Disable linemarker output in -E mode
\\ -pedantic Warn on language extensions
\\ -pedantic-errors Error on language extensions
\\ --rtlib=<arg> Compiler runtime library to use (libgcc or compiler-rt)
@@ -262,9 +280,12 @@ pub fn parseArgs(
var pic_arg: []const u8 = "";
var declspec_attrs: ?bool = null;
var ms_extensions: ?bool = null;
+ var strip = true;
+ var debug: ?backend.CodeGenOptions.DebugFormat = null;
+ var emulate: ?LangOpts.Compiler = null;
while (i < args.len) : (i += 1) {
const arg = args[i];
- if (mem.startsWith(u8, arg, "-") and arg.len > 1) {
+ if (arg.len > 1 and arg[0] == '-') {
if (mem.eql(u8, arg, "--help")) {
try stdout.print(usage, .{args[0]});
try stdout.flush();
@@ -329,7 +350,7 @@ pub fn parseArgs(
} else if (mem.eql(u8, arg, "-fapple-kext")) {
d.apple_kext = true;
} else if (option(arg, "-mcmodel=")) |cmodel| {
- d.cmodel = std.meta.stringToEnum(std.builtin.CodeModel, cmodel) orelse
+ d.comp.cmodel = std.meta.stringToEnum(std.builtin.CodeModel, cmodel) orelse
return d.fatal("unsupported machine code model: '{s}'", .{arg});
} else if (mem.eql(u8, arg, "-mkernel")) {
d.mkernel = true;
@@ -339,14 +360,47 @@ pub fn parseArgs(
d.mabicalls = true;
} else if (mem.eql(u8, arg, "-mno-abicalls")) {
d.mabicalls = false;
+ } else if (mem.eql(u8, arg, "-mcpu")) {
+ i += 1;
+ if (i >= args.len) {
+ try d.err("expected argument after -mcpu", .{});
+ continue;
+ }
+ d.raw_cpu = args[i];
+ } else if (option(arg, "-mcpu=")) |cpu| {
+ d.raw_cpu = cpu;
+ } else if (mem.eql(u8, arg, "-M") or mem.eql(u8, arg, "--dependencies")) {
+ d.dependencies.m = true;
+ // -M implies -w and -E
+ d.diagnostics.state.ignore_warnings = true;
+ d.only_preprocess = true;
+ } else if (mem.eql(u8, arg, "-MD") or mem.eql(u8, arg, "--write-dependencies")) {
+ d.dependencies.md = true;
+ } else if (mem.startsWith(u8, arg, "-MF")) {
+ var path = arg["-MF".len..];
+ if (path.len == 0) {
+ i += 1;
+ if (i >= args.len) {
+ try d.err("expected argument after -MF", .{});
+ continue;
+ }
+ path = args[i];
+ }
+ d.dependencies.file = path;
+ } else if (mem.eql(u8, arg, "-MV")) {
+ d.dependencies.format = .nmake;
} else if (mem.eql(u8, arg, "-fchar8_t")) {
d.comp.langopts.has_char8_t_override = true;
} else if (mem.eql(u8, arg, "-fno-char8_t")) {
d.comp.langopts.has_char8_t_override = false;
} else if (mem.eql(u8, arg, "-fcolor-diagnostics")) {
- d.color = true;
+ d.diagnostics.color = true;
} else if (mem.eql(u8, arg, "-fno-color-diagnostics")) {
- d.color = false;
+ d.diagnostics.color = false;
+ } else if (mem.eql(u8, arg, "-fcaret-diagnostics")) {
+ d.diagnostics.details = true;
+ } else if (mem.eql(u8, arg, "-fno-caret-diagnostics")) {
+ d.diagnostics.details = false;
} else if (mem.eql(u8, arg, "-fcommon")) {
d.comp.code_gen_options.common = true;
} else if (mem.eql(u8, arg, "-fno-common")) {
@@ -356,9 +410,31 @@ pub fn parseArgs(
} else if (mem.eql(u8, arg, "-fno-dollars-in-identifiers")) {
d.comp.langopts.dollars_in_identifiers = false;
} else if (mem.eql(u8, arg, "-g")) {
- d.comp.code_gen_options.debug = true;
+ strip = false;
} else if (mem.eql(u8, arg, "-g0")) {
- d.comp.code_gen_options.debug = false;
+ strip = true;
+ } else if (mem.eql(u8, arg, "-gcodeview")) {
+ debug = .code_view;
+ } else if (mem.eql(u8, arg, "-gdwarf32")) {
+ debug = .{ .dwarf = .@"32" };
+ } else if (mem.eql(u8, arg, "-gdwarf64")) {
+ debug = .{ .dwarf = .@"64" };
+ } else if (mem.eql(u8, arg, "-gdwarf") or
+ mem.eql(u8, arg, "-gdwarf-2") or
+ mem.eql(u8, arg, "-gdwarf-3") or
+ mem.eql(u8, arg, "-gdwarf-4") or
+ mem.eql(u8, arg, "-gdwarf-5"))
+ {
+ d.comp.code_gen_options.dwarf_version = switch (arg[arg.len - 1]) {
+ '2' => .@"2",
+ '3' => .@"3",
+ '4' => .@"4",
+ '5' => .@"5",
+ else => .@"0",
+ };
+ if (debug == null or debug.? != .dwarf) {
+ debug = .{ .dwarf = .@"32" };
+ }
} else if (mem.eql(u8, arg, "-fdigraphs")) {
d.comp.langopts.digraphs = true;
} else if (mem.eql(u8, arg, "-fno-digraphs")) {
@@ -413,9 +489,9 @@ pub fn parseArgs(
ms_extensions = true;
} else if (mem.eql(u8, arg, "-fno-ms-extensions")) {
ms_extensions = false;
- } else if (mem.startsWith(u8, arg, "-fsyntax-only")) {
+ } else if (mem.eql(u8, arg, "-fsyntax-only")) {
d.only_syntax = true;
- } else if (mem.startsWith(u8, arg, "-fno-syntax-only")) {
+ } else if (mem.eql(u8, arg, "-fno-syntax-only")) {
d.only_syntax = false;
} else if (mem.eql(u8, arg, "-fgnuc-version=")) {
gnuc_version = "0";
@@ -483,12 +559,7 @@ pub fn parseArgs(
try d.err("invalid compiler '{s}'", .{arg});
continue;
};
- d.comp.langopts.setEmulatedCompiler(compiler);
- switch (d.comp.langopts.emulate) {
- .clang => try d.diagnostics.set("clang", .off),
- .gcc => try d.diagnostics.set("gnu", .off),
- .msvc => try d.diagnostics.set("microsoft", .off),
- }
+ emulate = compiler;
} else if (option(arg, "-ffp-eval-method=")) |fp_method_str| {
const fp_eval_method = std.meta.stringToEnum(LangOpts.FPEvalMethod, fp_method_str) orelse .indeterminate;
if (fp_eval_method == .indeterminate) {
@@ -554,8 +625,10 @@ pub fn parseArgs(
continue;
}
d.raw_target_triple = args[i];
+ emulate = null;
} else if (option(arg, "--target=")) |triple| {
d.raw_target_triple = triple;
+ emulate = null;
} else if (mem.eql(u8, arg, "--verbose-ast")) {
d.verbose_ast = true;
} else if (mem.eql(u8, arg, "--verbose-pp")) {
@@ -571,6 +644,10 @@ pub fn parseArgs(
d.comp.langopts.preserve_comments = true;
d.comp.langopts.preserve_comments_in_macros = true;
comment_arg = arg;
+ } else if (option(arg, "-fuse-ld=")) |linker_name| {
+ d.use_linker = linker_name;
+ } else if (mem.eql(u8, arg, "-fuse-ld=")) {
+ d.use_linker = null;
} else if (option(arg, "--ld-path=")) |linker_path| {
d.linker_path = linker_path;
} else if (mem.eql(u8, arg, "-r")) {
@@ -624,6 +701,33 @@ pub fn parseArgs(
} else {
try d.err("invalid unwind library name '{s}'", .{unwindlib});
}
+ } else if (mem.startsWith(u8, arg, "-x")) {
+ var lang = arg["-x".len..];
+ if (lang.len == 0) {
+ i += 1;
+ if (i >= args.len) {
+ try d.err("expected argument after -x", .{});
+ continue;
+ }
+ lang = args[i];
+ }
+ if (!mem.eql(u8, lang, "none") and !mem.eql(u8, lang, "c")) {
+ try d.err("language not recognized: '{s}'", .{lang});
+ }
+ } else if (mem.startsWith(u8, arg, "-flto")) {
+ const rest = arg["-flto".len..];
+ if (rest.len == 0 or
+ mem.eql(u8, rest, "=auto") or
+ mem.eql(u8, rest, "=full") or
+ mem.eql(u8, rest, "=jobserver") or
+ mem.eql(u8, rest, "=thin"))
+ {
+ try d.warn("lto not supported", .{});
+ } else {
+ return d.fatal("invalid lto mode: '{s}'", .{arg});
+ }
+ } else if (mem.eql(u8, arg, "-fno-lto")) {
+ // nothing to do
} else {
try d.warn("unknown argument '{s}'", .{arg});
}
@@ -636,17 +740,33 @@ pub fn parseArgs(
try d.inputs.append(d.comp.gpa, source);
}
}
- if (d.raw_target_triple) |triple| triple: {
- const query = std.Target.Query.parse(.{ .arch_os_abi = triple }) catch {
- try d.err("invalid target '{s}'", .{triple});
- d.raw_target_triple = null;
- break :triple;
+ {
+ var diags: std.Target.Query.ParseOptions.Diagnostics = .{};
+ const opts: std.Target.Query.ParseOptions = .{
+ .arch_os_abi = d.raw_target_triple orelse "native",
+ .cpu_features = d.raw_cpu,
+ .diagnostics = &diags,
+ };
+ const query = std.Target.Query.parse(opts) catch |er| switch (er) {
+ error.UnknownCpuModel => {
+ return d.fatal("unknown CPU: '{s}'", .{diags.cpu_name.?});
+ },
+ error.UnknownCpuFeature => {
+ return d.fatal("unknown CPU feature: '{s}'", .{diags.unknown_feature_name.?});
+ },
+ error.UnknownArchitecture => {
+ return d.fatal("unknown architecture: '{s}'", .{diags.unknown_architecture_name.?});
+ },
+ else => |e| return d.fatal("unable to parse target query '{s}': {s}", .{
+ opts.arch_os_abi, @errorName(e),
+ }),
};
- const target = std.zig.system.resolveTargetQuery(query) catch |e| {
+ d.comp.target = std.zig.system.resolveTargetQuery(query) catch |e| {
return d.fatal("unable to resolve target: {s}", .{errorDescription(e)});
};
- d.comp.target = target;
- d.comp.langopts.setEmulatedCompiler(target_util.systemCompiler(target));
+ }
+ if (emulate != null or d.raw_target_triple != null) {
+ d.comp.langopts.setEmulatedCompiler(emulate orelse target_util.systemCompiler(d.comp.target));
switch (d.comp.langopts.emulate) {
.clang => try d.diagnostics.set("clang", .off),
.gcc => try d.diagnostics.set("gnu", .off),
@@ -673,6 +793,19 @@ pub fn parseArgs(
const pic_level, const is_pie = try d.getPICMode(pic_arg);
d.comp.code_gen_options.pic_level = pic_level;
d.comp.code_gen_options.is_pie = is_pie;
+ d.comp.code_gen_options.debug = debug: {
+ if (strip) break :debug .strip;
+ if (debug) |explicit| break :debug explicit;
+ break :debug switch (d.comp.target.ofmt) {
+ .elf, .goff, .macho, .wasm, .xcoff => .{ .dwarf = .@"32" },
+ .coff => .code_view,
+ .c => switch (d.comp.target.os.tag) {
+ .windows, .uefi => .code_view,
+ else => .{ .dwarf = .@"32" },
+ },
+ .spirv, .hex, .raw, .plan9 => .strip,
+ };
+ };
if (declspec_attrs) |some| d.comp.langopts.declspec_attrs = some;
if (ms_extensions) |some| d.comp.langopts.setMSExtensions(some);
return false;
@@ -728,6 +861,7 @@ pub fn fatal(d: *Driver, comptime fmt: []const u8, args: anytype) error{ FatalEr
}
pub fn printDiagnosticsStats(d: *Driver) void {
+ if (!d.diagnostics.details) return;
const warnings = d.diagnostics.warnings;
const errors = d.diagnostics.errors;
@@ -743,14 +877,14 @@ pub fn printDiagnosticsStats(d: *Driver) void {
}
pub fn detectConfig(d: *Driver, file: std.fs.File) std.Io.tty.Config {
- if (d.color == true) return .escape_codes;
- if (d.color == false) return .no_color;
+ if (d.diagnostics.color == false) return .no_color;
+ const force_color = d.diagnostics.color == true;
if (file.supportsAnsiEscapeCodes()) return .escape_codes;
if (@import("builtin").os.tag == .windows and file.isTty()) {
var info: std.os.windows.CONSOLE_SCREEN_BUFFER_INFO = undefined;
- if (std.os.windows.kernel32.GetConsoleScreenBufferInfo(file.handle, &info) != std.os.windows.TRUE) {
- return .no_color;
+ if (std.os.windows.kernel32.GetConsoleScreenBufferInfo(file.handle, &info) == std.os.windows.FALSE) {
+ return if (force_color) .escape_codes else .no_color;
}
return .{ .windows_api = .{
.handle = file.handle,
@@ -758,7 +892,7 @@ pub fn detectConfig(d: *Driver, file: std.fs.File) std.Io.tty.Config {
} };
}
- return .no_color;
+ return if (force_color) .escape_codes else .no_color;
}
pub fn errorDescription(e: anyerror) []const u8 {
@@ -851,6 +985,47 @@ pub fn main(d: *Driver, tc: *Toolchain, args: []const []const u8, comptime fast_
if (fast_exit) std.process.exit(0);
}
+/// Initializes a DepFile if requested by driver options.
+pub fn initDepFile(d: *Driver, source: Source, buf: *[std.fs.max_name_bytes]u8) Compilation.Error!?DepFile {
+ if (!d.dependencies.m and !d.dependencies.md) return null;
+ var dep_file: DepFile = .{
+ .target = undefined,
+ .format = d.dependencies.format,
+ };
+
+ if (d.dependencies.md and d.output_name != null) {
+ dep_file.target = d.output_name.?;
+ } else {
+ const args = .{
+ std.fs.path.stem(source.path),
+ d.comp.target.ofmt.fileExt(d.comp.target.cpu.arch),
+ };
+ dep_file.target = std.fmt.bufPrint(buf, "{s}{s}", args) catch
+ return d.fatal("dependency file name too long for filesystem '{s}{s}'", args);
+ }
+
+ try dep_file.addDependency(d.comp.gpa, source.path);
+ errdefer comptime unreachable;
+
+ return dep_file;
+}
+
+/// Returns name requested for the dependency file or null for stdout.
+pub fn getDepFileName(d: *Driver, source: Source, buf: *[std.fs.max_name_bytes]u8) Compilation.Error!?[]const u8 {
+ if (d.dependencies.file) |file| {
+ if (std.mem.eql(u8, file, "-")) return null;
+ return file;
+ }
+ if (!d.dependencies.md) {
+ if (d.output_name) |name| return name;
+ return null;
+ }
+
+ const base_name = std.fs.path.stem(d.output_name orelse source.path);
+ return std.fmt.bufPrint(buf, "{s}.d", .{base_name}) catch
+ return d.fatal("dependency file name too long for filesystem: {s}.d", .{base_name});
+}
+
fn getRandomFilename(d: *Driver, buf: *[std.fs.max_name_bytes]u8, extension: []const u8) ![]const u8 {
const random_bytes_count = 12;
const sub_path_len = comptime std.fs.base64_encoder.calcSize(random_bytes_count);
@@ -925,6 +1100,12 @@ fn processSource(
var pp = try Preprocessor.initDefault(d.comp);
defer pp.deinit();
+ var name_buf: [std.fs.max_name_bytes]u8 = undefined;
+ var opt_dep_file = try d.initDepFile(source, &name_buf);
+ defer if (opt_dep_file) |*dep_file| dep_file.deinit(pp.gpa);
+
+ if (opt_dep_file) |*dep_file| pp.dep_file = dep_file;
+
if (d.comp.langopts.ms_extensions) {
d.comp.ms_cwd_source_id = source.id;
}
@@ -943,6 +1124,22 @@ fn processSource(
try pp.preprocessSources(&.{ source, builtin, user_macros });
+ var writer_buf: [4096]u8 = undefined;
+ if (opt_dep_file) |dep_file| {
+ const dep_file_name = try d.getDepFileName(source, writer_buf[0..std.fs.max_name_bytes]);
+
+ const file = if (dep_file_name) |path|
+ d.comp.cwd.createFile(path, .{}) catch |er|
+ return d.fatal("unable to create dependency file '{s}': {s}", .{ path, errorDescription(er) })
+ else
+ std.fs.File.stdout();
+ defer if (dep_file_name != null) file.close();
+
+ var file_writer = file.writer(&writer_buf);
+ dep_file.write(&file_writer.interface) catch
+ return d.fatal("unable to write dependency file: {s}", .{errorDescription(file_writer.err.?)});
+ }
+
if (d.only_preprocess) {
d.printDiagnosticsStats();
@@ -951,6 +1148,11 @@ fn processSource(
return;
}
+ if (d.dependencies.m and !d.dependencies.md) {
+ if (fast_exit) std.process.exit(1); // Not linking, no need for cleanup.
+ return;
+ }
+
const file = if (d.output_name) |some|
d.comp.cwd.createFile(some, .{}) catch |er|
return d.fatal("unable to create output file '{s}': {s}", .{ some, errorDescription(er) })
@@ -997,7 +1199,6 @@ fn processSource(
);
}
- var name_buf: [std.fs.max_name_bytes]u8 = undefined;
const out_file_name = try d.getOutFileName(source, &name_buf);
if (d.use_assembly_backend) {
@@ -1039,8 +1240,7 @@ fn processSource(
defer ir.deinit(d.comp.gpa);
if (d.verbose_ir) {
- var stdout_buf: [4096]u8 = undefined;
- var stdout = std.fs.File.stdout().writer(&stdout_buf);
+ var stdout = std.fs.File.stdout().writer(&writer_buf);
ir.dump(d.comp.gpa, d.detectConfig(stdout.file), &stdout.interface) catch {};
}
@@ -1065,8 +1265,7 @@ fn processSource(
return d.fatal("unable to create output file '{s}': {s}", .{ out_file_name, errorDescription(er) });
defer out_file.close();
- var file_buf: [4096]u8 = undefined;
- var file_writer = out_file.writer(&file_buf);
+ var file_writer = out_file.writer(&writer_buf);
obj.finish(&file_writer.interface) catch
return d.fatal("could not output to object file '{s}': {s}", .{ out_file_name, errorDescription(file_writer.err.?) });
}
@@ -1236,7 +1435,7 @@ pub fn getPICMode(d: *Driver, lastpic: []const u8) Compilation.Error!struct { ba
} else {
pic, pie = .{ false, false };
if (target_util.isPS(target)) {
- if (d.cmodel != .kernel) {
+ if (d.comp.cmodel != .kernel) {
pic = true;
try d.warn(
"option '{s}' was ignored by the {s} toolchain, using '-fPIC'",
lib/compiler/aro/aro/Parser.zig
@@ -6904,6 +6904,9 @@ pub const Result = struct {
try p.err(l_paren, .invalid_union_cast, .{res.qt});
return error.ParsingFailed;
}
+ } else if (dest_qt.eql(res.qt, p.comp)) {
+ try p.err(l_paren, .cast_to_same_type, .{dest_qt});
+ cast_kind = .no_op;
} else {
try p.err(l_paren, .invalid_cast_type, .{dest_qt});
return error.ParsingFailed;
@@ -8720,7 +8723,9 @@ fn fieldAccess(
};
if (record_ty.layout == null) {
- std.debug.assert(is_ptr);
+ // Invalid use of incomplete type, error reported elsewhere.
+ if (!is_ptr) return error.ParsingFailed;
+
try p.err(field_name_tok - 2, .deref_incomplete_ty_ptr, .{expr_base_qt});
return error.ParsingFailed;
}
lib/compiler/aro/aro/Preprocessor.zig
@@ -7,6 +7,7 @@ const Attribute = @import("Attribute.zig");
const Compilation = @import("Compilation.zig");
const Error = Compilation.Error;
const Diagnostics = @import("Diagnostics.zig");
+const DepFile = @import("DepFile.zig");
const features = @import("features.zig");
const Hideset = @import("Hideset.zig");
const Parser = @import("Parser.zig");
@@ -157,6 +158,9 @@ hideset: Hideset,
source_epoch: SourceEpoch,
m_times: std.AutoHashMapUnmanaged(Source.Id, u64) = .{},
+/// The dependency file tracking all includes and embeds.
+dep_file: ?*DepFile = null,
+
pub const parse = Parser.parse;
pub const Linemarkers = enum {
@@ -169,7 +173,7 @@ pub const Linemarkers = enum {
};
pub fn init(comp: *Compilation, source_epoch: SourceEpoch) Preprocessor {
- const pp = Preprocessor{
+ const pp: Preprocessor = .{
.comp = comp,
.diagnostics = comp.diagnostics,
.gpa = comp.gpa,
@@ -1614,13 +1618,18 @@ fn handleBuiltinMacro(pp: *Preprocessor, builtin: RawToken.Id, param_toks: []con
else => unreachable,
};
const filename = include_str[1 .. include_str.len - 1];
- if (builtin == .macro_param_has_include or pp.include_depth == 0) {
- if (builtin == .macro_param_has_include_next) {
- try pp.err(src_loc, .include_next_outside_header, .{});
+ const res = res: {
+ if (builtin == .macro_param_has_include or pp.include_depth == 0) {
+ if (builtin == .macro_param_has_include_next) {
+ try pp.err(src_loc, .include_next_outside_header, .{});
+ }
+ break :res try pp.comp.hasInclude(filename, src_loc.id, include_type, .first);
}
- return pp.comp.hasInclude(filename, src_loc.id, include_type, .first);
- }
- return pp.comp.hasInclude(filename, src_loc.id, include_type, .next);
+ break :res try pp.comp.hasInclude(filename, src_loc.id, include_type, .next);
+ };
+
+ if (res) if (pp.dep_file) |dep_file| try dep_file.addDependencyDupe(pp.gpa, pp.comp.arena, filename);
+ return res;
},
else => unreachable,
}
@@ -1929,7 +1938,7 @@ fn expandFuncMacro(
else => unreachable,
};
const filename = include_str[1 .. include_str.len - 1];
- const contents = (try pp.comp.findEmbed(filename, arg[0].loc.id, include_type, .limited(1))) orelse
+ const contents = (try pp.comp.findEmbed(filename, arg[0].loc.id, include_type, .limited(1), pp.dep_file)) orelse
break :res not_found;
defer pp.comp.gpa.free(contents);
@@ -2537,7 +2546,7 @@ fn expandedSliceExtra(pp: *const Preprocessor, tok: anytype, macro_ws_handling:
if (tok.id.lexeme()) |some| {
if (!tok.id.allowsDigraphs(pp.comp.langopts) and !(tok.id == .macro_ws and macro_ws_handling == .preserve_macro_ws)) return some;
}
- var tmp_tokenizer = Tokenizer{
+ var tmp_tokenizer: Tokenizer = .{
.buf = pp.comp.getSource(tok.loc.id).buf,
.langopts = pp.comp.langopts,
.index = tok.loc.byte_offset,
@@ -3087,7 +3096,7 @@ fn embed(pp: *Preprocessor, tokenizer: *Tokenizer) MacroError!void {
}
}
- const embed_bytes = (try pp.comp.findEmbed(filename, first.source, include_type, limit orelse .unlimited)) orelse
+ const embed_bytes = (try pp.comp.findEmbed(filename, first.source, include_type, limit orelse .unlimited, pp.dep_file)) orelse
return pp.fatalNotFound(filename_tok, filename);
defer pp.comp.gpa.free(embed_bytes);
@@ -3143,6 +3152,7 @@ fn include(pp: *Preprocessor, tokenizer: *Tokenizer, which: Compilation.WhichInc
if (pp.defines.contains(guard)) return;
}
+ if (pp.dep_file) |dep| try dep.addDependency(pp.gpa, new_source.path);
if (pp.verbose) {
pp.verboseLog(first, "include file {s}", .{new_source.path});
}
lib/compiler/aro/backend/CodeGenOptions.zig
@@ -11,7 +11,22 @@ pic_level: PicLevel,
is_pie: bool,
optimization_level: OptimizationLevel,
/// Generate debug information
-debug: bool,
+debug: DebugFormat,
+dwarf_version: DwarfVersion,
+
+pub const DebugFormat = union(enum) {
+ strip,
+ dwarf: std.dwarf.Format,
+ code_view,
+};
+
+pub const DwarfVersion = enum(u3) {
+ @"0" = 0,
+ @"2" = 2,
+ @"3" = 3,
+ @"4" = 4,
+ @"5" = 5,
+};
pub const PicLevel = enum(u8) {
/// Do not generate position-independent code
@@ -60,5 +75,6 @@ pub const default: @This() = .{
.pic_level = .none,
.is_pie = false,
.optimization_level = .@"0",
- .debug = false,
+ .debug = .strip,
+ .dwarf_version = .@"0",
};
lib/compiler/aro/include/float.h
@@ -0,0 +1,126 @@
+/* <float.h> for the Aro C compiler */
+
+#pragma once
+
+#undef FLT_RADIX
+#define FLT_RADIX __FLT_RADIX__
+
+#undef FLT_MANT_DIG
+#define FLT_MANT_DIG __FLT_MANT_DIG__
+
+#undef DBL_MANT_DIG
+#define DBL_MANT_DIG __DBL_MANT_DIG__
+
+#undef LDBL_MANT_DIG
+#define LDBL_MANT_DIG __LDBL_MANT_DIG__
+
+#if __STDC_VERSION__ >= 199901L
+#undef FLT_EVAL_METHOD
+#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__
+
+#undef DECIMAL_DIG
+#define DECIMAL_DIG __DECIMAL_DIG__
+#endif /* __STDC_VERSION__ >= 199901L */
+
+#undef FLT_DIG
+#define FLT_DIG __FLT_DIG__
+
+#undef DBL_DIG
+#define DBL_DIG __DBL_DIG__
+
+#undef LDBL_DIG
+#define LDBL_DIG __LDBL_DIG__
+
+#undef FLT_MIN_EXP
+#define FLT_MIN_EXP __FLT_MIN_EXP__
+
+#undef DBL_MIN_EXP
+#define DBL_MIN_EXP __DBL_MIN_EXP__
+
+#undef LDBL_MIN_EXP
+#define LDBL_MIN_EXP __LDBL_MIN_EXP__
+
+#undef FLT_MIN_10_EXP
+#define FLT_MIN_10_EXP __FLT_MIN_10_EXP__
+
+#undef DBL_MIN_10_EXP
+#define DBL_MIN_10_EXP __DBL_MIN_10_EXP__
+
+#undef LDBL_MIN_10_EXP
+#define LDBL_MIN_10_EXP __LDBL_MIN_10_EXP__
+
+#undef FLT_MAX_EXP
+#define FLT_MAX_EXP __FLT_MAX_EXP__
+
+#undef DBL_MAX_EXP
+#define DBL_MAX_EXP __DBL_MAX_EXP__
+
+#undef LDBL_MAX_EXP
+#define LDBL_MAX_EXP __LDBL_MAX_EXP__
+
+#undef FLT_MAX_10_EXP
+#define FLT_MAX_10_EXP __FLT_MAX_10_EXP__
+
+#undef DBL_MAX_10_EXP
+#define DBL_MAX_10_EXP __DBL_MAX_10_EXP__
+
+#undef LDBL_MAX_10_EXP
+#define LDBL_MAX_10_EXP __LDBL_MAX_10_EXP__
+
+#undef FLT_MAX
+#define FLT_MAX __FLT_MAX__
+
+#undef DBL_MAX
+#define DBL_MAX __DBL_MAX__
+
+#undef LDBL_MAX
+#define LDBL_MAX __LDBL_MAX__
+
+#undef FLT_EPSILON
+#define FLT_EPSILON __FLT_EPSILON__
+
+#undef DBL_EPSILON
+#define DBL_EPSILON __DBL_EPSILON__
+
+#undef LDBL_EPSILON
+#define LDBL_EPSILON __LDBL_EPSILON__
+
+#undef FLT_MIN
+#define FLT_MIN __FLT_MIN__
+
+#undef DBL_MIN
+#define DBL_MIN __DBL_MIN__
+
+#undef LDBL_MIN
+#define LDBL_MIN __LDBL_MIN__
+
+#if __STDC_VERSION__ >= 201112L
+
+#undef FLT_TRUE_MIN
+#define FLT_TRUE_MIN __FLT_DENORM_MIN__
+
+#undef DBL_TRUE_MIN
+#define DBL_TRUE_MIN __DBL_DENORM_MIN__
+
+#undef LDBL_TRUE_MIN
+#define LDBL_TRUE_MIN __LDBL_DENORM_MIN__
+
+#undef FLT_DECIMAL_DIG
+#define FLT_DECIMAL_DIG __FLT_DECIMAL_DIG__
+
+#undef DBL_DECIMAL_DIG
+#define DBL_DECIMAL_DIG __DBL_DECIMAL_DIG__
+
+#undef LDBL_DECIMAL_DIG
+#define LDBL_DECIMAL_DIG __LDBL_DECIMAL_DIG__
+
+#undef FLT_HAS_SUBNORM
+#define FLT_HAS_SUBNORM __FLT_HAS_DENORM__
+
+#undef DBL_HAS_SUBNORM
+#define DBL_HAS_SUBNORM __DBL_HAS_DENORM__
+
+#undef LDBL_HAS_SUBNORM
+#define LDBL_HAS_SUBNORM __LDBL_HAS_DENORM__
+
+#endif /* __STDC_VERSION__ >= 201112L */
lib/compiler/aro/include/iso646.h
@@ -0,0 +1,15 @@
+/* <iso646.h> for the Aro C compiler */
+
+#pragma once
+
+#define and &&
+#define and_eq &=
+#define bitand &
+#define bitor |
+#define compl ~
+#define not !
+#define not_eq !=
+#define or ||
+#define or_eq |=
+#define xor ^
+#define xor_eq ^=
lib/compiler/aro/include/limits.h
@@ -0,0 +1,124 @@
+/* <limits.h> for the Aro C compiler */
+
+#pragma once
+
+/* GlibC will try to include_next GCC's limits.h which will fail.
+ Define _GCC_LIMITS_H_ to prevent it. */
+#if defined __GNUC__ && !defined _GCC_LIMITS_H_
+#define _GCC_LIMITS_H_
+#endif
+
+/* Include the system's limits.h */
+#if __STDC_HOSTED__ && __has_include_next(<limits.h>)
+#include_next <limits.h>
+#endif
+
+#undef SCHAR_MAX
+#define SCHAR_MAX __SCHAR_MAX__
+
+#undef SHRT_MAX
+#define SHRT_MAX __SHRT_MAX__
+
+#undef INT_MAX
+#define INT_MAX __INT_MAX__
+
+#undef LONG_MAX
+#define LONG_MAX __LONG_MAX__
+
+#undef SCHAR_MIN
+#define SCHAR_MIN (-__SCHAR_MAX__-1)
+
+#undef SHRT_MIN
+#define SHRT_MIN (-__SHRT_MAX__ -1)
+
+#undef INT_MIN
+#define INT_MIN (-__INT_MAX__ -1)
+
+#undef LONG_MIN
+#define LONG_MIN (-__LONG_MAX__ -1L)
+
+#undef UCHAR_MAX
+#define UCHAR_MAX (__SCHAR_MAX__*2 +1)
+
+#undef USHRT_MAX
+#define USHRT_MAX (__SHRT_MAX__ *2 +1)
+
+#undef UINT_MAX
+#define UINT_MAX (__INT_MAX__ *2U +1U)
+
+#undef ULONG_MAX
+#define ULONG_MAX (__LONG_MAX__ *2UL+1UL)
+
+#ifndef MB_LEN_MAX
+#define MB_LEN_MAX 1
+#endif
+
+#undef CHAR_BIT
+#define CHAR_BIT __CHAR_BIT__
+
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
+
+#undef BOOL_WIDTH
+#define BOOL_WIDTH __BOOL_WIDTH__
+
+#undef CHAR_WIDTH
+#define CHAR_WIDTH CHAR_BIT
+
+#undef SCHAR_WIDTH
+#define SCHAR_WIDTH CHAR_BIT
+
+#undef UCHAR_WIDTH
+#define UCHAR_WIDTH CHAR_BIT
+
+#undef USHRT_WIDTH
+#define USHRT_WIDTH __SHRT_WIDTH__
+
+#undef SHRT_WIDTH
+#define SHRT_WIDTH __SHRT_WIDTH__
+
+#undef UINT_WIDTH
+#define UINT_WIDTH __INT_WIDTH__
+
+#undef INT_WIDTH
+#define INT_WIDTH __INT_WIDTH__
+
+#undef ULONG_WIDTH
+#define ULONG_WIDTH __LONG_WIDTH__
+
+#undef LONG_WIDTH
+#define LONG_WIDTH __LONG_WIDTH__
+
+#undef ULLONG_WIDTH
+#define ULLONG_WIDTH __LLONG_WIDTH__
+
+#undef LLONG_WIDTH
+#define LLONG_WIDTH __LLONG_WIDTH__
+
+#undef BITINT_MAXWIDTH
+#define BITINT_MAXWIDTH __BITINT_MAXWIDTH__
+
+#endif /* defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L */
+
+#undef CHAR_MIN
+#undef CHAR_MAX
+#ifdef __CHAR_UNSIGNED__
+#define CHAR_MIN 0
+#define CHAR_MAX UCHAR_MAX
+#else
+#define CHAR_MIN SCHAR_MIN
+#define CHAR_MAX __SCHAR_MAX__
+#endif
+
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+#undef LLONG_MIN
+#define LLONG_MIN (-__LONG_LONG_MAX__-1LL)
+
+#undef LLONG_MAX
+#define LLONG_MAX __LONG_LONG_MAX__
+
+#undef ULLONG_MAX
+#define ULLONG_MAX (__LONG_LONG_MAX__*2ULL+1ULL)
+
+#endif
+
lib/compiler/aro/include/stdalign.h
@@ -0,0 +1,11 @@
+/* <stdalign.h> for the Aro C compiler */
+
+#pragma once
+#if __STDC_VERSION__ < 202311L
+
+#define alignas _Alignas
+#define alignof _Alignof
+
+#define __alignas_is_defined 1
+#define __alignof_is_defined 1
+#endif
lib/compiler/aro/include/stdarg.h
@@ -0,0 +1,28 @@
+/* <stdarg.h> for the Aro C compiler */
+
+#pragma once
+/* Todo: Set to 202311L once header is compliant with C23 */
+#define __STDC_VERSION_STDARG_H__ 0
+
+typedef __builtin_va_list va_list;
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L
+/* C23 no longer requires the second parameter */
+#define va_start(ap, ...) __builtin_va_start(ap, __VA_ARGS__)
+#else
+#define va_start(ap, param) __builtin_va_start(ap, param)
+#endif
+#define va_end(ap) __builtin_va_end(ap)
+#define va_arg(ap, type) __builtin_va_arg(ap, type)
+
+/* GCC and Clang always define __va_copy */
+#define __va_copy(d, s) __builtin_va_copy(d, s)
+
+/* but va_copy only on c99+ or when strict ansi mode is turned off */
+#if __STDC_VERSION__ >= 199901L || !defined(__STRICT_ANSI__)
+#define va_copy(d, s) __builtin_va_copy(d, s)
+#endif
+
+#ifndef __GNUC_VA_LIST
+#define __GNUC_VA_LIST 1
+typedef __builtin_va_list __gnuc_va_list;
+#endif
lib/compiler/aro/include/stdatomic.h
@@ -0,0 +1,138 @@
+/* <stdatomic.h> for the Aro C compiler */
+
+#pragma once
+
+#define __STDC_VERSION_STDATOMIC_H__ 202311L
+
+#if __STDC_HOSTED__ && __has_include_next(<stdatomic.h>)
+#include_next <stdatomic.h>
+#else
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define ATOMIC_BOOL_LOCK_FREE __ATOMIC_BOOL_LOCK_FREE
+#define ATOMIC_CHAR_LOCK_FREE __ATOMIC_CHAR_LOCK_FREE
+#define ATOMIC_CHAR16_T_LOCK_FREE __ATOMIC_CHAR16_T_LOCK_FREE
+#define ATOMIC_CHAR32_T_LOCK_FREE __ATOMIC_CHAR32_T_LOCK_FREE
+#define ATOMIC_WCHAR_T_LOCK_FREE __ATOMIC_WCHAR_T_LOCK_FREE
+#define ATOMIC_SHORT_LOCK_FREE __ATOMIC_SHORT_LOCK_FREE
+#define ATOMIC_INT_LOCK_FREE __ATOMIC_INT_LOCK_FREE
+#define ATOMIC_LONG_LOCK_FREE __ATOMIC_LONG_LOCK_FREE
+#define ATOMIC_LLONG_LOCK_FREE __ATOMIC_LLONG_LOCK_FREE
+#define ATOMIC_POINTER_LOCK_FREE __ATOMIC_POINTER_LOCK_FREE
+#if defined(__ATOMIC_CHAR8_T_LOCK_FREE)
+#define ATOMIC_CHAR8_T_LOCK_FREE __ATOMIC_CHAR8_T_LOCK_FREE
+#endif
+
+#if __STDC_VERSION__ < 202311L
+/* ATOMIC_VAR_INIT was removed in C23 */
+#define ATOMIC_VAR_INIT(value) (value)
+#endif
+
+#define atomic_init __c11_atomic_init
+
+typedef enum memory_order {
+ memory_order_relaxed = __ATOMIC_RELAXED,
+ memory_order_consume = __ATOMIC_CONSUME,
+ memory_order_acquire = __ATOMIC_ACQUIRE,
+ memory_order_release = __ATOMIC_RELEASE,
+ memory_order_acq_rel = __ATOMIC_ACQ_REL,
+ memory_order_seq_cst = __ATOMIC_SEQ_CST
+} memory_order;
+
+#define kill_dependency(y) (y)
+
+void atomic_thread_fence(memory_order);
+void atomic_signal_fence(memory_order);
+
+#define atomic_thread_fence(order) __c11_atomic_thread_fence(order)
+#define atomic_signal_fence(order) __c11_atomic_signal_fence(order)
+
+#define atomic_is_lock_free(obj) __c11_atomic_is_lock_free(sizeof(*(obj)))
+
+typedef _Atomic(_Bool) atomic_bool;
+typedef _Atomic(char) atomic_char;
+typedef _Atomic(signed char) atomic_schar;
+typedef _Atomic(unsigned char) atomic_uchar;
+typedef _Atomic(short) atomic_short;
+typedef _Atomic(unsigned short) atomic_ushort;
+typedef _Atomic(int) atomic_int;
+typedef _Atomic(unsigned int) atomic_uint;
+typedef _Atomic(long) atomic_long;
+typedef _Atomic(unsigned long) atomic_ulong;
+typedef _Atomic(long long) atomic_llong;
+typedef _Atomic(unsigned long long) atomic_ullong;
+typedef _Atomic(uint_least16_t) atomic_char16_t;
+typedef _Atomic(uint_least32_t) atomic_char32_t;
+typedef _Atomic(wchar_t) atomic_wchar_t;
+typedef _Atomic(int_least8_t) atomic_int_least8_t;
+typedef _Atomic(uint_least8_t) atomic_uint_least8_t;
+typedef _Atomic(int_least16_t) atomic_int_least16_t;
+typedef _Atomic(uint_least16_t) atomic_uint_least16_t;
+typedef _Atomic(int_least32_t) atomic_int_least32_t;
+typedef _Atomic(uint_least32_t) atomic_uint_least32_t;
+typedef _Atomic(int_least64_t) atomic_int_least64_t;
+typedef _Atomic(uint_least64_t) atomic_uint_least64_t;
+typedef _Atomic(int_fast8_t) atomic_int_fast8_t;
+typedef _Atomic(uint_fast8_t) atomic_uint_fast8_t;
+typedef _Atomic(int_fast16_t) atomic_int_fast16_t;
+typedef _Atomic(uint_fast16_t) atomic_uint_fast16_t;
+typedef _Atomic(int_fast32_t) atomic_int_fast32_t;
+typedef _Atomic(uint_fast32_t) atomic_uint_fast32_t;
+typedef _Atomic(int_fast64_t) atomic_int_fast64_t;
+typedef _Atomic(uint_fast64_t) atomic_uint_fast64_t;
+typedef _Atomic(intptr_t) atomic_intptr_t;
+typedef _Atomic(uintptr_t) atomic_uintptr_t;
+typedef _Atomic(size_t) atomic_size_t;
+typedef _Atomic(ptrdiff_t) atomic_ptrdiff_t;
+typedef _Atomic(intmax_t) atomic_intmax_t;
+typedef _Atomic(uintmax_t) atomic_uintmax_t;
+
+#define atomic_store(object, desired) __c11_atomic_store(object, desired, __ATOMIC_SEQ_CST)
+#define atomic_store_explicit __c11_atomic_store
+
+#define atomic_load(object) __c11_atomic_load(object, __ATOMIC_SEQ_CST)
+#define atomic_load_explicit __c11_atomic_load
+
+#define atomic_exchange(object, desired) __c11_atomic_exchange(object, desired, __ATOMIC_SEQ_CST)
+#define atomic_exchange_explicit __c11_atomic_exchange
+
+#define atomic_compare_exchange_strong(object, expected, desired) __c11_atomic_compare_exchange_strong(object, expected, desired, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
+#define atomic_compare_exchange_strong_explicit __c11_atomic_compare_exchange_strong
+
+#define atomic_compare_exchange_weak(object, expected, desired) __c11_atomic_compare_exchange_weak(object, expected, desired, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
+#define atomic_compare_exchange_weak_explicit __c11_atomic_compare_exchange_weak
+
+#define atomic_fetch_add(object, operand) __c11_atomic_fetch_add(object, operand, __ATOMIC_SEQ_CST)
+#define atomic_fetch_add_explicit __c11_atomic_fetch_add
+
+#define atomic_fetch_sub(object, operand) __c11_atomic_fetch_sub(object, operand, __ATOMIC_SEQ_CST)
+#define atomic_fetch_sub_explicit __c11_atomic_fetch_sub
+
+#define atomic_fetch_or(object, operand) __c11_atomic_fetch_or(object, operand, __ATOMIC_SEQ_CST)
+#define atomic_fetch_or_explicit __c11_atomic_fetch_or
+
+#define atomic_fetch_xor(object, operand) __c11_atomic_fetch_xor(object, operand, __ATOMIC_SEQ_CST)
+#define atomic_fetch_xor_explicit __c11_atomic_fetch_xor
+
+#define atomic_fetch_and(object, operand) __c11_atomic_fetch_and(object, operand, __ATOMIC_SEQ_CST)
+#define atomic_fetch_and_explicit __c11_atomic_fetch_and
+
+typedef struct atomic_flag { atomic_bool _Value; } atomic_flag;
+
+#define ATOMIC_FLAG_INIT { 0 }
+
+_Bool atomic_flag_test_and_set(volatile atomic_flag *);
+_Bool atomic_flag_test_and_set_explicit(volatile atomic_flag *, memory_order);
+void atomic_flag_clear(volatile atomic_flag *);
+void atomic_flag_clear_explicit(volatile atomic_flag *, memory_order);
+
+#define atomic_flag_test_and_set(object) __c11_atomic_exchange(&(object)->_Value, 1, __ATOMIC_SEQ_CST)
+#define atomic_flag_test_and_set_explicit(object, order) __c11_atomic_exchange(&(object)->_Value, 1, order)
+
+#define atomic_flag_clear(object) __c11_atomic_store(&(object)->_Value, 0, __ATOMIC_SEQ_CST)
+#define atomic_flag_clear_explicit(object, order) __c11_atomic_store(&(object)->_Value, 0, order)
+
+
+#endif
lib/compiler/aro/include/stdbool.h
@@ -0,0 +1,13 @@
+/* <stdbool.h> for the Aro C compiler */
+
+#pragma once
+
+#if __STDC_VERSION__ < 202311L
+#define bool _Bool
+
+#define true 1
+#define false 0
+
+#define __bool_true_false_are_defined 1
+
+#endif
lib/compiler/aro/include/stdckdint.h
@@ -0,0 +1,9 @@
+/* <stdckdint.h> for the Aro C compiler */
+
+#pragma once
+
+#define __STDC_VERSION_STDCKDINT_H__ 202311L
+
+#define ckd_add(result, a, b) __builtin_add_overflow(a, b, result)
+#define ckd_sub(result, a, b) __builtin_sub_overflow(a, b, result)
+#define ckd_mul(result, a, b) __builtin_mul_overflow(a, b, result)
lib/compiler/aro/include/stddef.h
@@ -0,0 +1,31 @@
+/* <stddef.h> for the Aro C compiler */
+
+#pragma once
+
+#define __STDC_VERSION_STDDEF_H__ 202311L
+
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+typedef __SIZE_TYPE__ size_t;
+typedef __WCHAR_TYPE__ wchar_t;
+
+/* define max_align_t to match GCC and Clang */
+typedef struct {
+ long long __aro_max_align_ll;
+ long double __aro_max_align_ld;
+} max_align_t;
+
+#define NULL ((void*)0)
+#define offsetof(T, member) __builtin_offsetof(T, member)
+
+#if __STDC_VERSION__ >= 202311L
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wpre-c23-compat"
+ typedef typeof(nullptr) nullptr_t;
+# pragma GCC diagnostic pop
+
+# if defined unreachable
+# error unreachable() is a standard macro in C23
+# else
+# define unreachable() __builtin_unreachable()
+# endif
+#endif
lib/compiler/aro/include/stdint.h
@@ -0,0 +1,289 @@
+/* <stdint.h> for the Aro C compiler */
+
+#pragma once
+
+
+#if __STDC_HOSTED__ && __has_include_next(<stdint.h>)
+
+# include_next <stdint.h>
+
+#else
+
+#define __stdint_int_c_cat(X, Y) X ## Y
+#define __stdint_int_c(V, SUFFIX) __stdint_int_c_cat(V, SUFFIX)
+#define __stdint_uint_c(V, SUFFIX) __stdint_int_c_cat(V##U, SUFFIX)
+
+#define INTPTR_MIN (-__INTPTR_MAX__-1)
+#define INTPTR_MAX __INTPTR_MAX__
+#define UINTPTR_MAX __UINTPTR_MAX__
+#define PTRDIFF_MIN (-__PTRDIFF_MAX__-1)
+#define PTRDIFF_MAX __PTRDIFF_MAX__
+#define SIZE_MAX __SIZE_MAX__
+#define INTMAX_MIN (-__INTMAX_MAX__-1)
+#define INTMAX_MAX __INTMAX_MAX__
+#define UINTMAX_MAX __UINTMAX_MAX__
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
+# define INTPTR_WIDTH __INTPTR_WIDTH__
+# define UINTPTR_WIDTH __UINTPTR_WIDTH__
+# define INTMAX_WIDTH __INTMAX_WIDTH__
+# define UINTMAX_WIDTH __UINTMAX_WIDTH__
+# define PTRDIFF_WIDTH __PTRDIFF_WIDTH__
+# define SIZE_WIDTH __SIZE_WIDTH__
+# define WCHAR_WIDTH __WCHAR_WIDTH__
+#endif
+
+typedef __INTMAX_TYPE__ intmax_t;
+typedef __UINTMAX_TYPE__ uintmax_t;
+
+#ifndef _INTPTR_T
+# ifndef __intptr_t_defined
+ typedef __INTPTR_TYPE__ intptr_t;
+# define __intptr_t_defined
+# define _INTPTR_T
+# endif
+#endif
+
+#ifndef _UINTPTR_T
+ typedef __UINTPTR_TYPE__ uintptr_t;
+# define _UINTPTR_T
+#endif
+
+
+#ifdef __INT64_TYPE__
+# ifndef __int8_t_defined /* glibc sys/types.h also defines int64_t*/
+ typedef __INT64_TYPE__ int64_t;
+# endif /* __int8_t_defined */
+ typedef __UINT64_TYPE__ uint64_t;
+
+# undef __int64_c_suffix
+# undef __int32_c_suffix
+# undef __int16_c_suffix
+# undef __int8_c_suffix
+# ifdef __INT64_C_SUFFIX__
+# define __int64_c_suffix __INT64_C_SUFFIX__
+# define __int32_c_suffix __INT64_C_SUFFIX__
+# define __int16_c_suffix __INT64_C_SUFFIX__
+# define __int8_c_suffix __INT64_C_SUFFIX__
+# endif /* __INT64_C_SUFFIX__ */
+
+# ifdef __int64_c_suffix
+# define INT64_C(v) (__stdint_int_c(v, __int64_c_suffix))
+# define UINT64_C(v) (__stdint_uint_c(v, __int64_c_suffix))
+# else
+# define INT64_C(v) (v)
+# define UINT64_C(v) (v ## U)
+# endif /* __int64_c_suffix */
+
+# define INT64_MAX INT64_C( 9223372036854775807)
+# define INT64_MIN (-INT64_C( 9223372036854775807)-1)
+# define UINT64_MAX UINT64_C(18446744073709551615)
+# if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
+# define UINT64_WIDTH 64
+# define INT64_WIDTH UINT64_WIDTH
+# endif /* __STDC_VERSION__ */
+
+#endif /* __INT64_TYPE__ */
+
+#ifdef __INT32_TYPE__
+# ifndef __int8_t_defined /* glibc sys/types.h also defines int32_t*/
+ typedef __INT32_TYPE__ int32_t;
+# endif /* __int8_t_defined */
+ typedef __UINT32_TYPE__ uint32_t;
+
+# undef __int32_c_suffix
+# undef __int16_c_suffix
+# undef __int8_c_suffix
+# ifdef __INT32_C_SUFFIX__
+# define __int32_c_suffix __INT32_C_SUFFIX__
+# define __int16_c_suffix __INT32_C_SUFFIX__
+# define __int8_c_suffix __INT32_C_SUFFIX__
+# endif /* __INT32_C_SUFFIX__ */
+
+# ifdef __int32_c_suffix
+# define INT32_C(v) (__stdint_int_c(v, __int32_c_suffix))
+# define UINT32_C(v) (__stdint_uint_c(v, __int32_c_suffix))
+# else
+# define INT32_C(v) (v)
+# define UINT32_C(v) (v ## U)
+# endif /* __int32_c_suffix */
+
+# define INT32_MAX INT32_C( 2147483647)
+# define INT32_MIN (-INT32_C( 2147483647)-1)
+# define UINT32_MAX UINT32_C(4294967295)
+# if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
+# define UINT32_WIDTH 32
+# define INT32_WIDTH UINT32_WIDTH
+# endif /* __STDC_VERSION__ */
+
+#endif /* __INT32_TYPE__ */
+
+#ifdef __INT16_TYPE__
+# ifndef __int8_t_defined /* glibc sys/types.h also defines int16_t*/
+ typedef __INT16_TYPE__ int16_t;
+# endif /* __int8_t_defined */
+ typedef __UINT16_TYPE__ uint16_t;
+
+# undef __int16_c_suffix
+# undef __int8_c_suffix
+# ifdef __INT16_C_SUFFIX__
+# define __int16_c_suffix __INT16_C_SUFFIX__
+# define __int8_c_suffix __INT16_C_SUFFIX__
+# endif /* __INT16_C_SUFFIX__ */
+
+# ifdef __int16_c_suffix
+# define INT16_C(v) (__stdint_int_c(v, __int16_c_suffix))
+# define UINT16_C(v) (__stdint_uint_c(v, __int16_c_suffix))
+# else
+# define INT16_C(v) (v)
+# define UINT16_C(v) (v ## U)
+# endif /* __int16_c_suffix */
+
+# define INT16_MAX INT16_C( 32767)
+# define INT16_MIN (-INT16_C( 32767)-1)
+# define UINT16_MAX UINT16_C(65535)
+# if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
+# define UINT16_WIDTH 16
+# define INT16_WIDTH UINT16_WIDTH
+# endif /* __STDC_VERSION__ */
+
+#endif /* __INT16_TYPE__ */
+
+#ifdef __INT8_TYPE__
+# ifndef __int8_t_defined /* glibc sys/types.h also defines int8_t*/
+ typedef __INT8_TYPE__ int8_t;
+# endif /* __int8_t_defined */
+ typedef __UINT8_TYPE__ uint8_t;
+
+# undef __int8_c_suffix
+# ifdef __INT8_C_SUFFIX__
+# define __int8_c_suffix __INT8_C_SUFFIX__
+# endif /* __INT8_C_SUFFIX__ */
+
+# ifdef __int8_c_suffix
+# define INT8_C(v) (__stdint_int_c(v, __int8_c_suffix))
+# define UINT8_C(v) (__stdint_uint_c(v, __int8_c_suffix))
+# else
+# define INT8_C(v) (v)
+# define UINT8_C(v) (v ## U)
+# endif /* __int8_c_suffix */
+
+# define INT8_MAX INT8_C(127)
+# define INT8_MIN (-INT8_C(127)-1)
+# define UINT8_MAX UINT8_C(255)
+# if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
+# define UINT8_WIDTH 8
+# define INT8_WIDTH UINT8_WIDTH
+# endif /* __STDC_VERSION__ */
+
+#endif /* __INT8_TYPE__ */
+
+typedef __INT_LEAST64_TYPE__ int_least64_t;
+typedef __INT_LEAST32_TYPE__ int_least32_t;
+typedef __INT_LEAST16_TYPE__ int_least16_t;
+typedef __INT_LEAST8_TYPE__ int_least8_t;
+
+typedef __UINT_LEAST64_TYPE__ uint_least64_t;
+typedef __UINT_LEAST32_TYPE__ uint_least32_t;
+typedef __UINT_LEAST16_TYPE__ uint_least16_t;
+typedef __UINT_LEAST8_TYPE__ uint_least8_t;
+
+#define INT_LEAST8_MAX __INT_LEAST8_MAX__
+#define INT_LEAST8_MIN (-__INT_LEAST8_MAX__-1)
+#define UINT_LEAST8_MAX __UINT_LEAST8_MAX__
+
+#define INT_LEAST16_MAX __INT_LEAST16_MAX__
+#define INT_LEAST16_MIN (-__INT_LEAST16_MAX__-1)
+#define UINT_LEAST16_MAX __UINT_LEAST16_MAX__
+
+#define INT_LEAST32_MAX __INT_LEAST32_MAX__
+#define INT_LEAST32_MIN (-__INT_LEAST32_MAX__-1)
+#define UINT_LEAST32_MAX __UINT_LEAST32_MAX__
+
+#define INT_LEAST64_MAX __INT_LEAST64_MAX__
+#define INT_LEAST64_MIN (-__INT_LEAST64_MAX__-1)
+#define UINT_LEAST64_MAX __UINT_LEAST64_MAX__
+
+
+typedef __INT_FAST64_TYPE__ int_fast64_t;
+typedef __INT_FAST32_TYPE__ int_fast32_t;
+typedef __INT_FAST16_TYPE__ int_fast16_t;
+typedef __INT_FAST8_TYPE__ int_fast8_t;
+
+typedef __UINT_FAST64_TYPE__ uint_fast64_t;
+typedef __UINT_FAST32_TYPE__ uint_fast32_t;
+typedef __UINT_FAST16_TYPE__ uint_fast16_t;
+typedef __UINT_FAST8_TYPE__ uint_fast8_t;
+
+#define INT_FAST8_MAX __INT_FAST8_MAX__
+#define INT_FAST8_MIN (-__INT_FAST8_MAX__-1)
+#define UINT_FAST8_MAX __UINT_FAST8_MAX__
+
+#define INT_FAST16_MAX __INT_FAST16_MAX__
+#define INT_FAST16_MIN (-__INT_FAST16_MAX__-1)
+#define UINT_FAST16_MAX __UINT_FAST16_MAX__
+
+#define INT_FAST32_MAX __INT_FAST32_MAX__
+#define INT_FAST32_MIN (-__INT_FAST32_MAX__-1)
+#define UINT_FAST32_MAX __UINT_FAST32_MAX__
+
+#define INT_FAST64_MAX __INT_FAST64_MAX__
+#define INT_FAST64_MIN (-__INT_FAST64_MAX__-1)
+#define UINT_FAST64_MAX __UINT_FAST64_MAX__
+
+
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
+
+#define INT_FAST8_WIDTH __INT_FAST8_WIDTH__
+#define UINT_FAST8_WIDTH __INT_FAST8_WIDTH__
+#define INT_LEAST8_WIDTH __INT_LEAST8_WIDTH__
+#define UINT_LEAST8_WIDTH __INT_LEAST8_WIDTH__
+
+#define INT_FAST16_WIDTH __INT_FAST16_WIDTH__
+#define UINT_FAST16_WIDTH __INT_FAST16_WIDTH__
+#define INT_LEAST16_WIDTH __INT_LEAST16_WIDTH__
+#define UINT_LEAST16_WIDTH __INT_LEAST16_WIDTH__
+
+#define INT_FAST32_WIDTH __INT_FAST32_WIDTH__
+#define UINT_FAST32_WIDTH __INT_FAST32_WIDTH__
+#define INT_LEAST32_WIDTH __INT_LEAST32_WIDTH__
+#define UINT_LEAST32_WIDTH __INT_LEAST32_WIDTH__
+
+#define INT_FAST64_WIDTH __INT_FAST64_WIDTH__
+#define UINT_FAST64_WIDTH __INT_FAST64_WIDTH__
+#define INT_LEAST64_WIDTH __INT_LEAST64_WIDTH__
+#define UINT_LEAST64_WIDTH __INT_LEAST64_WIDTH__
+
+#endif
+
+#ifdef __SIZEOF_INT128__
+typedef signed __int128 int128_t;
+typedef unsigned __int128 uint128_t;
+typedef signed __int128 int_fast128_t;
+typedef unsigned __int128 uint_fast128_t;
+typedef signed __int128 int_least128_t;
+typedef unsigned __int128 uint_least128_t;
+# define UINT128_MAX ((uint128_t)-1)
+# define INT128_MAX ((int128_t)+(UINT128_MAX/2))
+# define INT128_MIN (-INT128_MAX-1)
+# define UINT_LEAST128_MAX UINT128_MAX
+# define INT_LEAST128_MAX INT128_MAX
+# define INT_LEAST128_MIN INT128_MIN
+# define UINT_FAST128_MAX UINT128_MAX
+# define INT_FAST128_MAX INT128_MAX
+# define INT_FAST128_MIN INT128_MIN
+# define INT128_WIDTH 128
+# define UINT128_WIDTH 128
+# define INT_LEAST128_WIDTH 128
+# define UINT_LEAST128_WIDTH 128
+# define INT_FAST128_WIDTH 128
+# define UINT_FAST128_WIDTH 128
+# if UINT128_WIDTH > __LLONG_WIDTH__
+# define INT128_C(N) ((int_least128_t)+N ## WB)
+# define UINT128_C(N) ((uint_least128_t)+N ## WBU)
+# else
+# define INT128_C(N) ((int_least128_t)+N ## LL)
+# define UINT128_C(N) ((uint_least128_t)+N ## LLU)
+# endif
+#endif
+
+#endif /* __STDC_HOSTED__ && __has_include_next(<stdint.h>) */
lib/compiler/aro/include/stdnoreturn.h
@@ -0,0 +1,6 @@
+/* <stdnoreturn.h> for the Aro C compiler */
+
+#pragma once
+
+#define noreturn _Noreturn
+#define __noreturn_is_defined 1
lib/compiler/aro/include/varargs.h
@@ -0,0 +1,3 @@
+/* <varargs.h> for the Aro C compiler */
+#pragma once
+#error please use <stdarg.h> instead of <varargs.h>
lib/compiler/translate-c/main.zig
@@ -109,8 +109,6 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8) !void {
var macro_buf: std.ArrayListUnmanaged(u8) = .empty;
defer macro_buf.deinit(gpa);
- try macro_buf.appendSlice(gpa, "#define __TRANSLATE_C__ 1\n");
-
var discard_buf: [256]u8 = undefined;
var discarding: std.io.Writer.Discarding = .init(&discard_buf);
assert(!try d.parseArgs(&discarding.writer, ¯o_buf, aro_args));
@@ -146,6 +144,12 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8) !void {
var pp = try aro.Preprocessor.initDefault(d.comp);
defer pp.deinit();
+ var name_buf: [std.fs.max_name_bytes]u8 = undefined;
+ var opt_dep_file = try d.initDepFile(source, &name_buf);
+ defer if (opt_dep_file) |*dep_file| dep_file.deinit(pp.gpa);
+
+ if (opt_dep_file) |*dep_file| pp.dep_file = dep_file;
+
try pp.preprocessSources(&.{ source, builtin_macros, user_macros });
var c_tree = try pp.parse();
@@ -156,6 +160,22 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8) !void {
return error.FatalError;
}
+ var out_buf: [4096]u8 = undefined;
+ if (opt_dep_file) |dep_file| {
+ const dep_file_name = try d.getDepFileName(source, out_buf[0..std.fs.max_name_bytes]);
+
+ const file = if (dep_file_name) |path|
+ d.comp.cwd.createFile(path, .{}) catch |er|
+ return d.fatal("unable to create dependency file '{s}': {s}", .{ path, aro.Driver.errorDescription(er) })
+ else
+ std.fs.File.stdout();
+ defer if (dep_file_name != null) file.close();
+
+ var file_writer = file.writer(&out_buf);
+ dep_file.write(&file_writer.interface) catch
+ return d.fatal("unable to write dependency file: {s}", .{aro.Driver.errorDescription(file_writer.err.?)});
+ }
+
const rendered_zig = try Translator.translate(.{
.gpa = gpa,
.comp = d.comp,
@@ -182,7 +202,6 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8) !void {
out_file_path = path;
}
- var out_buf: [4096]u8 = undefined;
var out_writer = out_file.writer(&out_buf);
out_writer.interface.writeAll(rendered_zig) catch
return d.fatal("failed to write result to '{s}': {s}", .{ out_file_path, aro.Driver.errorDescription(out_writer.err.?) });
lib/compiler/translate-c/Translator.zig
@@ -171,7 +171,7 @@ pub const Options = struct {
tree: *const aro.Tree,
};
-pub fn translate(options: Options) ![]u8 {
+pub fn translate(options: Options) mem.Allocator.Error![]u8 {
const gpa = options.gpa;
var arena_allocator = std.heap.ArenaAllocator.init(gpa);
defer arena_allocator.deinit();
@@ -219,19 +219,19 @@ pub fn translate(options: Options) ![]u8 {
var aw: std.Io.Writer.Allocating = .init(gpa);
defer aw.deinit();
- try aw.writer.writeAll(
+ aw.writer.writeAll(
\\pub const __builtin = @import("std").zig.c_translation.builtins;
\\pub const __helpers = @import("std").zig.c_translation.helpers;
\\
\\
- );
+ ) catch return error.OutOfMemory;
var zig_ast = try ast.render(gpa, translator.global_scope.nodes.items);
defer {
gpa.free(zig_ast.source);
zig_ast.deinit(gpa);
}
- try zig_ast.render(gpa, &aw.writer, .{});
+ zig_ast.render(gpa, &aw.writer, .{}) catch return error.OutOfMemory;
return aw.toOwnedSlice();
}
src/libs/mingw.zig
@@ -333,7 +333,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
defer std.debug.unlockStderrWriter();
for (aro_comp.diagnostics.output.to_list.messages.items) |msg| {
if (msg.kind == .@"fatal error" or msg.kind == .@"error") {
- aro.Diagnostics.writeToWriter(msg, w, std.io.tty.detectConfig(std.fs.File.stderr())) catch {};
+ msg.write(w, .detect(std.fs.File.stderr()), true) catch {};
return error.AroPreprocessorFailed;
}
}
build.zig
@@ -1144,7 +1144,6 @@ fn toNativePathSep(b: *std.Build, s: []const u8) []u8 {
const zig_cpp_sources = [_][]const u8{
// These are planned to stay even when we are self-hosted.
"src/zig_llvm.cpp",
- "src/zig_clang.cpp",
"src/zig_llvm-ar.cpp",
"src/zig_clang_driver.cpp",
"src/zig_clang_cc1_main.cpp",