update aro and translate-c sources

This commit is contained in:
Veikka Tuominen 2025-07-28 14:37:57 +03:00 committed by Andrew Kelley
parent e8e8d7e5c8
commit e7a622fb33
24 changed files with 1577 additions and 141 deletions

View file

@ -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",

View file

@ -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,7 +351,13 @@ fn generateSystemDefines(comp: *Compilation, w: *std.Io.Writer) !void {
// architecture macros
switch (comp.target.cpu.arch) {
.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__");
@ -362,8 +370,7 @@ fn generateSystemDefines(comp: *Compilation, w: *std.Io.Writer) !void {
\\
);
}
},
.x86 => {
} else {
try defineStd(w, "i386", is_gnu);
if (comp.target.os.tag == .windows and comp.target.abi == .msvc) {
@ -374,6 +381,177 @@ fn generateSystemDefines(comp: *Compilation, w: *std.Io.Writer) !void {
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.cpu.has(.x86, .sahf) or (comp.langopts.emulate == .clang and comp.target.cpu.arch == .x86)) {
try define(w, "__LAHF_SAHF__");
}
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,
.mipsel,
@ -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,

78
lib/compiler/aro/aro/DepFile.zig vendored Normal file
View file

@ -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);
}
},
}
}

View file

@ -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();
}

View file

@ -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 target = std.zig.system.resolveTargetQuery(query) catch |e| {
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),
}),
};
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'",

View file

@ -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;
}

View file

@ -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,
};

View file

@ -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];
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, .{});
}
return pp.comp.hasInclude(filename, src_loc.id, include_type, .first);
break :res try 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});
}

View file

@ -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",
};

126
lib/compiler/aro/include/float.h vendored Normal file
View file

@ -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 */

15
lib/compiler/aro/include/iso646.h vendored Normal file
View file

@ -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 ^=

124
lib/compiler/aro/include/limits.h vendored Normal file
View file

@ -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

11
lib/compiler/aro/include/stdalign.h vendored Normal file
View file

@ -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

28
lib/compiler/aro/include/stdarg.h vendored Normal file
View file

@ -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

138
lib/compiler/aro/include/stdatomic.h vendored Normal file
View file

@ -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

13
lib/compiler/aro/include/stdbool.h vendored Normal file
View file

@ -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

9
lib/compiler/aro/include/stdckdint.h vendored Normal file
View file

@ -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)

31
lib/compiler/aro/include/stddef.h vendored Normal file
View file

@ -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

289
lib/compiler/aro/include/stdint.h vendored Normal file
View file

@ -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>) */

View file

@ -0,0 +1,6 @@
/* <stdnoreturn.h> for the Aro C compiler */
#pragma once
#define noreturn _Noreturn
#define __noreturn_is_defined 1

3
lib/compiler/aro/include/varargs.h vendored Normal file
View file

@ -0,0 +1,3 @@
/* <varargs.h> for the Aro C compiler */
#pragma once
#error please use <stdarg.h> instead of <varargs.h>

View file

@ -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();
}

View file

@ -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, &macro_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.?) });

View file

@ -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;
}
}