authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2025-09-14 16:41:44+03:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-09-24 20:01:19-07:00
logd83c76eb5af687210e3cc856b3f808f7e5f5e68f
tree2013762f112f58f33af58cde7d7c710d9e46204b
parente05073b9e4a7a7a860779d3977a98ee6cd4b6391

update aro & translate-c


17 files changed, 278 insertions(+), 196 deletions(-)

lib/compiler/aro/aro/Attribute.zig+1-6
...@@ -792,12 +792,7 @@ pub fn normalize(name: []const u8) []const u8 {...@@ -792,12 +792,7 @@ pub fn normalize(name: []const u8) []const u8 {
792}792}
793793
794fn ignoredAttrErr(p: *Parser, tok: TokenIndex, attr: Attribute.Tag, context: []const u8) !void {794fn ignoredAttrErr(p: *Parser, tok: TokenIndex, attr: Attribute.Tag, context: []const u8) !void {
795 const strings_top = p.strings.items.len;795 try p.err(tok, .ignored_attribute, .{ @tagName(attr), context });
796 defer p.strings.items.len = strings_top;
797
798 try p.strings.print("attribute '{s}' ignored on {s}", .{ @tagName(attr), context });
799 const str = try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
800 try p.errStr(.ignored_attribute, tok, str);
801}796}
802797
803pub fn applyParameterAttributes(p: *Parser, qt: QualType, attr_buf_start: usize, diagnostic: ?Parser.Diagnostic) !QualType {798pub fn applyParameterAttributes(p: *Parser, qt: QualType, attr_buf_start: usize, diagnostic: ?Parser.Diagnostic) !QualType {
lib/compiler/aro/aro/Compilation.zig+45-12
...@@ -132,6 +132,8 @@ sources: std.StringArrayHashMapUnmanaged(Source) = .empty,...@@ -132,6 +132,8 @@ sources: std.StringArrayHashMapUnmanaged(Source) = .empty,
132/// Allocated into `gpa`, but keys are externally managed.132/// Allocated into `gpa`, but keys are externally managed.
133include_dirs: std.ArrayList([]const u8) = .empty,133include_dirs: std.ArrayList([]const u8) = .empty,
134/// Allocated into `gpa`, but keys are externally managed.134/// Allocated into `gpa`, but keys are externally managed.
135iquote_include_dirs: std.ArrayList([]const u8) = .empty,
136/// Allocated into `gpa`, but keys are externally managed.
135system_include_dirs: std.ArrayList([]const u8) = .empty,137system_include_dirs: std.ArrayList([]const u8) = .empty,
136/// Allocated into `gpa`, but keys are externally managed.138/// Allocated into `gpa`, but keys are externally managed.
137after_include_dirs: std.ArrayList([]const u8) = .empty,139after_include_dirs: std.ArrayList([]const u8) = .empty,
...@@ -192,6 +194,7 @@ pub fn deinit(comp: *Compilation) void {...@@ -192,6 +194,7 @@ pub fn deinit(comp: *Compilation) void {
192 }194 }
193 comp.sources.deinit(gpa);195 comp.sources.deinit(gpa);
194 comp.include_dirs.deinit(gpa);196 comp.include_dirs.deinit(gpa);
197 comp.iquote_include_dirs.deinit(gpa);
195 comp.system_include_dirs.deinit(gpa);198 comp.system_include_dirs.deinit(gpa);
196 comp.after_include_dirs.deinit(gpa);199 comp.after_include_dirs.deinit(gpa);
197 comp.framework_dirs.deinit(gpa);200 comp.framework_dirs.deinit(gpa);
...@@ -240,12 +243,26 @@ fn generateSystemDefines(comp: *Compilation, w: *std.Io.Writer) !void {...@@ -240,12 +243,26 @@ fn generateSystemDefines(comp: *Compilation, w: *std.Io.Writer) !void {
240 const ptr_width = comp.target.ptrBitWidth();243 const ptr_width = comp.target.ptrBitWidth();
241 const is_gnu = comp.langopts.standard.isGNU();244 const is_gnu = comp.langopts.standard.isGNU();
242245
243 if (comp.langopts.gnuc_version > 0) {246 const gnuc_version = comp.langopts.gnuc_version orelse comp.langopts.emulate.defaultGccVersion();
244 try w.print("#define __GNUC__ {d}\n", .{comp.langopts.gnuc_version / 10_000});247 if (gnuc_version > 0) {
245 try w.print("#define __GNUC_MINOR__ {d}\n", .{comp.langopts.gnuc_version / 100 % 100});248 try w.print("#define __GNUC__ {d}\n", .{gnuc_version / 10_000});
246 try w.print("#define __GNUC_PATCHLEVEL__ {d}\n", .{comp.langopts.gnuc_version % 100});249 try w.print("#define __GNUC_MINOR__ {d}\n", .{gnuc_version / 100 % 100});
250 try w.print("#define __GNUC_PATCHLEVEL__ {d}\n", .{gnuc_version % 100});
247 }251 }
248252
253 try w.writeAll(
254 \\#define __ARO_EMULATE_CLANG__ 1
255 \\#define __ARO_EMULATE_GCC__ 2
256 \\#define __ARO_EMULATE_MSVC__ 3
257 \\
258 );
259 const emulated = switch (comp.langopts.emulate) {
260 .clang => "__ARO_EMULATE_CLANG__",
261 .gcc => "__ARO_EMULATE_GCC__",
262 .msvc => "__ARO_EMULATE_MSVC__",
263 };
264 try w.print("#define __ARO_EMULATE__ {s}\n", .{emulated});
265
249 if (comp.code_gen_options.optimization_level.hasAnyOptimizations()) {266 if (comp.code_gen_options.optimization_level.hasAnyOptimizations()) {
250 try define(w, "__OPTIMIZE__");267 try define(w, "__OPTIMIZE__");
251 }268 }
...@@ -330,6 +347,8 @@ fn generateSystemDefines(comp: *Compilation, w: *std.Io.Writer) !void {...@@ -330,6 +347,8 @@ fn generateSystemDefines(comp: *Compilation, w: *std.Io.Writer) !void {
330 => try define(w, "__APPLE__"),347 => try define(w, "__APPLE__"),
331 .wasi => try define(w, "__wasi__"),348 .wasi => try define(w, "__wasi__"),
332 .emscripten => try define(w, "__EMSCRIPTEN__"),349 .emscripten => try define(w, "__EMSCRIPTEN__"),
350 .@"3ds" => try define(w, "__3DS__"),
351 .vita => try define(w, "__vita__"),
333 else => {},352 else => {},
334 }353 }
335354
...@@ -431,10 +450,13 @@ fn generateSystemDefines(comp: *Compilation, w: *std.Io.Writer) !void {...@@ -431,10 +450,13 @@ fn generateSystemDefines(comp: *Compilation, w: *std.Io.Writer) !void {
431 .{ .f16c, "__F16C__" },450 .{ .f16c, "__F16C__" },
432 .{ .gfni, "__GFNI__" },451 .{ .gfni, "__GFNI__" },
433 .{ .evex512, "__EVEX512__" },452 .{ .evex512, "__EVEX512__" },
434 .{ .avx10_1_256, "__AVX10_1__" },453
435 .{ .avx10_1_512, "__AVX10_1_512__" },454 .{ .avx10_1, "__AVX10_1__" },
436 .{ .avx10_2_256, "__AVX10_2__" },455 .{ .avx10_1, "__AVX10_1_512__" },
437 .{ .avx10_2_512, "__AVX10_2_512__" },456
457 .{ .avx10_2, "__AVX10_2__" },
458 .{ .avx10_2, "__AVX10_2_512__" },
459
438 .{ .avx512cd, "__AVX512CD__" },460 .{ .avx512cd, "__AVX512CD__" },
439 .{ .avx512vpopcntdq, "__AVX512VPOPCNTDQ__" },461 .{ .avx512vpopcntdq, "__AVX512VPOPCNTDQ__" },
440 .{ .avx512vnni, "__AVX512VNNI__" },462 .{ .avx512vnni, "__AVX512VNNI__" },
...@@ -935,7 +957,7 @@ fn generateSystemDefines(comp: *Compilation, w: *std.Io.Writer) !void {...@@ -935,7 +957,7 @@ fn generateSystemDefines(comp: *Compilation, w: *std.Io.Writer) !void {
935pub fn generateBuiltinMacros(comp: *Compilation, system_defines_mode: SystemDefinesMode) AddSourceError!Source {957pub fn generateBuiltinMacros(comp: *Compilation, system_defines_mode: SystemDefinesMode) AddSourceError!Source {
936 try comp.type_store.initNamedTypes(comp);958 try comp.type_store.initNamedTypes(comp);
937959
938 var allocating: std.io.Writer.Allocating = try .initCapacity(comp.gpa, 2 << 13);960 var allocating: std.Io.Writer.Allocating = try .initCapacity(comp.gpa, 2 << 13);
939 defer allocating.deinit();961 defer allocating.deinit();
940962
941 comp.writeBuiltinMacros(system_defines_mode, &allocating.writer) catch |err| switch (err) {963 comp.writeBuiltinMacros(system_defines_mode, &allocating.writer) catch |err| switch (err) {
...@@ -1297,6 +1319,11 @@ fn generateIntWidth(comp: *Compilation, w: *std.Io.Writer, name: []const u8, qt:...@@ -1297,6 +1319,11 @@ fn generateIntWidth(comp: *Compilation, w: *std.Io.Writer, name: []const u8, qt:
1297 try w.print("#define __{s}_WIDTH__ {d}\n", .{ name, qt.sizeof(comp) * 8 });1319 try w.print("#define __{s}_WIDTH__ {d}\n", .{ name, qt.sizeof(comp) * 8 });
1298}1320}
12991321
1322fn generateIntMaxAndWidth(comp: *Compilation, w: *std.Io.Writer, name: []const u8, qt: QualType) !void {
1323 try comp.generateIntMax(w, name, qt);
1324 try comp.generateIntWidth(w, name, qt);
1325}
1326
1300fn generateSizeofType(comp: *Compilation, w: *std.Io.Writer, name: []const u8, qt: QualType) !void {1327fn generateSizeofType(comp: *Compilation, w: *std.Io.Writer, name: []const u8, qt: QualType) !void {
1301 try w.print("#define {s} {d}\n", .{ name, qt.sizeof(comp) });1328 try w.print("#define {s} {d}\n", .{ name, qt.sizeof(comp) });
1302}1329}
...@@ -1597,7 +1624,7 @@ pub fn hasInclude(...@@ -1597,7 +1624,7 @@ pub fn hasInclude(
1597 which: WhichInclude,1624 which: WhichInclude,
1598 opt_dep_file: ?*DepFile,1625 opt_dep_file: ?*DepFile,
1599) Compilation.Error!bool {1626) Compilation.Error!bool {
1600 if (try FindInclude.run(comp, filename, switch (which) {1627 if (try FindInclude.run(comp, filename, include_type, switch (which) {
1601 .next => .{ .only_search_after_dir = comp.getSource(includer_token_source).path },1628 .next => .{ .only_search_after_dir = comp.getSource(includer_token_source).path },
1602 .first => switch (include_type) {1629 .first => switch (include_type) {
1603 .quotes => .{ .allow_same_dir = comp.getSource(includer_token_source).path },1630 .quotes => .{ .allow_same_dir = comp.getSource(includer_token_source).path },
...@@ -1629,6 +1656,7 @@ const FindInclude = struct {...@@ -1629,6 +1656,7 @@ const FindInclude = struct {
1629 fn run(1656 fn run(
1630 comp: *Compilation,1657 comp: *Compilation,
1631 include_path: []const u8,1658 include_path: []const u8,
1659 include_type: IncludeType,
1632 search_strat: union(enum) {1660 search_strat: union(enum) {
1633 allow_same_dir: []const u8,1661 allow_same_dir: []const u8,
1634 only_search,1662 only_search,
...@@ -1663,7 +1691,12 @@ const FindInclude = struct {...@@ -1663,7 +1691,12 @@ const FindInclude = struct {
1663 find.wait_for = std.fs.path.dirname(other_file);1691 find.wait_for = std.fs.path.dirname(other_file);
1664 },1692 },
1665 }1693 }
16661694 switch (include_type) {
1695 .quotes => for (comp.iquote_include_dirs.items) |dir| {
1696 if (try find.checkIncludeDir(dir, .user)) |res| return res;
1697 },
1698 .angle_brackets => {},
1699 }
1667 for (comp.include_dirs.items) |dir| {1700 for (comp.include_dirs.items) |dir| {
1668 if (try find.checkIncludeDir(dir, .user)) |res| return res;1701 if (try find.checkIncludeDir(dir, .user)) |res| return res;
1669 }1702 }
...@@ -1876,7 +1909,7 @@ pub fn findInclude(...@@ -1876,7 +1909,7 @@ pub fn findInclude(
1876 /// include vs include_next1909 /// include vs include_next
1877 which: WhichInclude,1910 which: WhichInclude,
1878) Compilation.Error!?Source {1911) Compilation.Error!?Source {
1879 const found = try FindInclude.run(comp, filename, switch (which) {1912 const found = try FindInclude.run(comp, filename, include_type, switch (which) {
1880 .next => .{ .only_search_after_dir = comp.getSource(includer_token.source).path },1913 .next => .{ .only_search_after_dir = comp.getSource(includer_token.source).path },
1881 .first => switch (include_type) {1914 .first => switch (include_type) {
1882 .quotes => .{ .allow_same_dir = comp.getSource(includer_token.source).path },1915 .quotes => .{ .allow_same_dir = comp.getSource(includer_token.source).path },
lib/compiler/aro/aro/Diagnostics.zig+18-9
...@@ -194,6 +194,7 @@ pub const Option = enum {...@@ -194,6 +194,7 @@ pub const Option = enum {
194 @"microsoft-anon-tag",194 @"microsoft-anon-tag",
195 @"out-of-scope-function",195 @"out-of-scope-function",
196 @"date-time",196 @"date-time",
197 @"variadic-macro-arguments-omitted",
197 @"attribute-todo",198 @"attribute-todo",
198199
199 /// GNU extensions200 /// GNU extensions
...@@ -496,27 +497,35 @@ pub fn formatArgs(w: *std.Io.Writer, fmt: []const u8, args: anytype) std.Io.Writ...@@ -496,27 +497,35 @@ pub fn formatArgs(w: *std.Io.Writer, fmt: []const u8, args: anytype) std.Io.Writ
496 else => switch (@typeInfo(@TypeOf(arg))) {497 else => switch (@typeInfo(@TypeOf(arg))) {
497 .int, .comptime_int => try Diagnostics.formatInt(w, fmt[i..], arg),498 .int, .comptime_int => try Diagnostics.formatInt(w, fmt[i..], arg),
498 .pointer => try Diagnostics.formatString(w, fmt[i..], arg),499 .pointer => try Diagnostics.formatString(w, fmt[i..], arg),
499 else => unreachable,500 else => comptime unreachable,
500 },501 },
501 };502 };
502 }503 }
503 try w.writeAll(fmt[i..]);504 try w.writeAll(fmt[i..]);
504}505}
505506
506pub fn formatString(w: *std.Io.Writer, fmt: []const u8, str: []const u8) std.Io.Writer.Error!usize {507pub fn templateIndex(w: *std.Io.Writer, fmt: []const u8, template: []const u8) std.Io.Writer.Error!usize {
507 const template = "{s}";508 const i = std.mem.indexOf(u8, fmt, template) orelse {
508 const i = std.mem.indexOf(u8, fmt, template).?;509 if (@import("builtin").mode == .Debug) {
510 std.debug.panic("template `{s}` not found in format string `{s}`", .{ template, fmt });
511 }
512 try w.print("template `{s}` not found in format string `{s}` (this is a bug in arocc)", .{ template, fmt });
513 return 0;
514 };
509 try w.writeAll(fmt[0..i]);515 try w.writeAll(fmt[0..i]);
510 try w.writeAll(str);
511 return i + template.len;516 return i + template.len;
512}517}
513518
519pub fn formatString(w: *std.Io.Writer, fmt: []const u8, str: []const u8) std.Io.Writer.Error!usize {
520 const i = templateIndex(w, fmt, "{s}");
521 try w.writeAll(str);
522 return i;
523}
524
514pub fn formatInt(w: *std.Io.Writer, fmt: []const u8, int: anytype) std.Io.Writer.Error!usize {525pub fn formatInt(w: *std.Io.Writer, fmt: []const u8, int: anytype) std.Io.Writer.Error!usize {
515 const template = "{d}";526 const i = templateIndex(w, fmt, "{d}");
516 const i = std.mem.indexOf(u8, fmt, template).?;
517 try w.writeAll(fmt[0..i]);
518 try w.printInt(int, 10, .lower, .{});527 try w.printInt(int, 10, .lower, .{});
519 return i + template.len;528 return i;
520}529}
521530
522fn addMessage(d: *Diagnostics, msg: Message) Compilation.Error!void {531fn addMessage(d: *Diagnostics, msg: Message) Compilation.Error!void {
lib/compiler/aro/aro/Driver.zig+20-6
...@@ -203,6 +203,7 @@ pub const usage =...@@ -203,6 +203,7 @@ pub const usage =
203 \\ -fuse-line-directives Use `#line <num>` linemarkers in preprocessed output203 \\ -fuse-line-directives Use `#line <num>` linemarkers in preprocessed output
204 \\ -fno-use-line-directives204 \\ -fno-use-line-directives
205 \\ Use `# <num>` linemarkers in preprocessed output205 \\ Use `# <num>` linemarkers in preprocessed output
206 \\ -iquote <dir> Add directory to QUOTE include search path
206 \\ -I <dir> Add directory to include search path207 \\ -I <dir> Add directory to include search path
207 \\ -idirafter <dir> Add directory to AFTER include search path208 \\ -idirafter <dir> Add directory to AFTER include search path
208 \\ -isystem <dir> Add directory to SYSTEM include search path209 \\ -isystem <dir> Add directory to SYSTEM include search path
...@@ -275,7 +276,7 @@ pub fn parseArgs(...@@ -275,7 +276,7 @@ pub fn parseArgs(
275 var i: usize = 1;276 var i: usize = 1;
276 var comment_arg: []const u8 = "";277 var comment_arg: []const u8 = "";
277 var hosted: ?bool = null;278 var hosted: ?bool = null;
278 var gnuc_version: []const u8 = "4.2.1"; // default value set by clang279 var gnuc_version: ?[]const u8 = null;
279 var pic_arg: []const u8 = "";280 var pic_arg: []const u8 = "";
280 var declspec_attrs: ?bool = null;281 var declspec_attrs: ?bool = null;
281 var ms_extensions: ?bool = null;282 var ms_extensions: ?bool = null;
...@@ -529,6 +530,17 @@ pub fn parseArgs(...@@ -529,6 +530,17 @@ pub fn parseArgs(
529 path = args[i];530 path = args[i];
530 }531 }
531 try d.comp.system_include_dirs.append(d.comp.gpa, path);532 try d.comp.system_include_dirs.append(d.comp.gpa, path);
533 } else if (mem.startsWith(u8, arg, "-iquote")) {
534 var path = arg["-iquote".len..];
535 if (path.len == 0) {
536 i += 1;
537 if (i >= args.len) {
538 try d.err("expected argument after -iquote", .{});
539 continue;
540 }
541 path = args[i];
542 }
543 try d.comp.iquote_include_dirs.append(d.comp.gpa, path);
532 } else if (mem.startsWith(u8, arg, "-F")) {544 } else if (mem.startsWith(u8, arg, "-F")) {
533 var path = arg["-F".len..];545 var path = arg["-F".len..];
534 if (path.len == 0) {546 if (path.len == 0) {
...@@ -784,11 +796,13 @@ pub fn parseArgs(...@@ -784,11 +796,13 @@ pub fn parseArgs(
784 d.comp.target.os.tag = .freestanding;796 d.comp.target.os.tag = .freestanding;
785 }797 }
786 }798 }
787 const version = GCCVersion.parse(gnuc_version);799 if (gnuc_version) |unwrapped| {
788 if (version.major == -1) {800 const version = GCCVersion.parse(unwrapped);
789 return d.fatal("invalid value '{0s}' in '-fgnuc-version={0s}'", .{gnuc_version});801 if (version.major == -1) {
802 return d.fatal("invalid value '{s}' in '-fgnuc-version={s}'", .{ unwrapped, unwrapped });
803 }
804 d.comp.langopts.gnuc_version = version.toUnsigned();
790 }805 }
791 d.comp.langopts.gnuc_version = version.toUnsigned();
792 const pic_level, const is_pie = try d.getPICMode(pic_arg);806 const pic_level, const is_pie = try d.getPICMode(pic_arg);
793 d.comp.code_gen_options.pic_level = pic_level;807 d.comp.code_gen_options.pic_level = pic_level;
794 d.comp.code_gen_options.is_pie = is_pie;808 d.comp.code_gen_options.is_pie = is_pie;
...@@ -1039,7 +1053,7 @@ fn getRandomFilename(d: *Driver, buf: *[std.fs.max_name_bytes]u8, extension: []c...@@ -1039,7 +1053,7 @@ fn getRandomFilename(d: *Driver, buf: *[std.fs.max_name_bytes]u8, extension: []c
10391053
1040 const fmt_template = "/tmp/{s}{s}";1054 const fmt_template = "/tmp/{s}{s}";
1041 const fmt_args = .{1055 const fmt_args = .{
1042 random_name,1056 @as([]const u8, &random_name),
1043 extension,1057 extension,
1044 };1058 };
1045 return std.fmt.bufPrint(buf, fmt_template, fmt_args) catch return d.fatal("Filename too long for filesystem: " ++ fmt_template, fmt_args);1059 return std.fmt.bufPrint(buf, fmt_template, fmt_args) catch return d.fatal("Filename too long for filesystem: " ++ fmt_template, fmt_args);
lib/compiler/aro/aro/Driver/GCCVersion.zig+1-1
...@@ -57,7 +57,7 @@ pub fn parse(text: []const u8) GCCVersion {...@@ -57,7 +57,7 @@ pub fn parse(text: []const u8) GCCVersion {
57 var good = bad;57 var good = bad;
5858
59 var it = mem.splitScalar(u8, text, '.');59 var it = mem.splitScalar(u8, text, '.');
60 const first = it.next().?;60 const first = it.first();
61 const second = it.next() orelse "";61 const second = it.next() orelse "";
62 const rest = it.next() orelse "";62 const rest = it.next() orelse "";
6363
lib/compiler/aro/aro/LangOpts.zig+9-1
...@@ -7,6 +7,14 @@ pub const Compiler = enum {...@@ -7,6 +7,14 @@ pub const Compiler = enum {
7 clang,7 clang,
8 gcc,8 gcc,
9 msvc,9 msvc,
10
11 pub fn defaultGccVersion(self: Compiler) u32 {
12 return switch (self) {
13 .clang => 4 * 10_000 + 2 * 100 + 1,
14 .gcc => 7 * 10_000 + 1 * 100 + 0,
15 .msvc => 0,
16 };
17 }
10};18};
1119
12/// The floating-point evaluation method for intermediate results within a single expression20/// The floating-point evaluation method for intermediate results within a single expression
...@@ -139,7 +147,7 @@ preserve_comments_in_macros: bool = false,...@@ -139,7 +147,7 @@ preserve_comments_in_macros: bool = false,
139/// Used ONLY for generating __GNUC__ and related macros. Does not control the presence/absence of any features147/// Used ONLY for generating __GNUC__ and related macros. Does not control the presence/absence of any features
140/// Encoded as major * 10,000 + minor * 100 + patch148/// Encoded as major * 10,000 + minor * 100 + patch
141/// e.g. 4.2.1 == 40201149/// e.g. 4.2.1 == 40201
142gnuc_version: u32 = 0,150gnuc_version: ?u32 = null,
143151
144pub fn setStandard(self: *LangOpts, name: []const u8) error{InvalidStandard}!void {152pub fn setStandard(self: *LangOpts, name: []const u8) error{InvalidStandard}!void {
145 self.standard = Standard.NameMap.get(name) orelse return error.InvalidStandard;153 self.standard = Standard.NameMap.get(name) orelse return error.InvalidStandard;
lib/compiler/aro/aro/Parser.zig+40-36
...@@ -469,7 +469,7 @@ fn formatArgs(p: *Parser, w: *std.Io.Writer, fmt: []const u8, args: anytype) !vo...@@ -469,7 +469,7 @@ fn formatArgs(p: *Parser, w: *std.Io.Writer, fmt: []const u8, args: anytype) !vo
469 else => switch (@typeInfo(@TypeOf(arg))) {469 else => switch (@typeInfo(@TypeOf(arg))) {
470 .int, .comptime_int => try Diagnostics.formatInt(w, fmt[i..], arg),470 .int, .comptime_int => try Diagnostics.formatInt(w, fmt[i..], arg),
471 .pointer => try Diagnostics.formatString(w, fmt[i..], arg),471 .pointer => try Diagnostics.formatString(w, fmt[i..], arg),
472 else => unreachable,472 else => comptime unreachable,
473 },473 },
474 };474 };
475 }475 }
...@@ -477,22 +477,18 @@ fn formatArgs(p: *Parser, w: *std.Io.Writer, fmt: []const u8, args: anytype) !vo...@@ -477,22 +477,18 @@ fn formatArgs(p: *Parser, w: *std.Io.Writer, fmt: []const u8, args: anytype) !vo
477}477}
478478
479fn formatTokenId(w: *std.Io.Writer, fmt: []const u8, tok_id: Tree.Token.Id) !usize {479fn formatTokenId(w: *std.Io.Writer, fmt: []const u8, tok_id: Tree.Token.Id) !usize {
480 const template = "{tok_id}";480 const i = Diagnostics.templateIndex(w, fmt, "{tok_id}");
481 const i = std.mem.indexOf(u8, fmt, template).?;
482 try w.writeAll(fmt[0..i]);
483 try w.writeAll(tok_id.symbol());481 try w.writeAll(tok_id.symbol());
484 return i + template.len;482 return i;
485}483}
486484
487fn formatQualType(p: *Parser, w: *std.Io.Writer, fmt: []const u8, qt: QualType) !usize {485fn formatQualType(p: *Parser, w: *std.Io.Writer, fmt: []const u8, qt: QualType) !usize {
488 const template = "{qt}";486 const i = Diagnostics.templateIndex(w, fmt, "{qt}");
489 const i = std.mem.indexOf(u8, fmt, template).?;
490 try w.writeAll(fmt[0..i]);
491 try w.writeByte('\'');487 try w.writeByte('\'');
492 try qt.print(p.comp, w);488 try qt.print(p.comp, w);
493 try w.writeByte('\'');489 try w.writeByte('\'');
494490
495 if (qt.isC23Auto()) return i + template.len;491 if (qt.isC23Auto()) return i;
496 if (qt.get(p.comp, .vector)) |vector_ty| {492 if (qt.get(p.comp, .vector)) |vector_ty| {
497 try w.print(" (vector of {d} '", .{vector_ty.len});493 try w.print(" (vector of {d} '", .{vector_ty.len});
498 try vector_ty.elem.printDesugared(p.comp, w);494 try vector_ty.elem.printDesugared(p.comp, w);
...@@ -502,14 +498,11 @@ fn formatQualType(p: *Parser, w: *std.Io.Writer, fmt: []const u8, qt: QualType)...@@ -502,14 +498,11 @@ fn formatQualType(p: *Parser, w: *std.Io.Writer, fmt: []const u8, qt: QualType)
502 try qt.printDesugared(p.comp, w);498 try qt.printDesugared(p.comp, w);
503 try w.writeAll("')");499 try w.writeAll("')");
504 }500 }
505 return i + template.len;501 return i;
506}502}
507503
508fn formatResult(p: *Parser, w: *std.Io.Writer, fmt: []const u8, res: Result) !usize {504fn formatResult(p: *Parser, w: *std.Io.Writer, fmt: []const u8, res: Result) !usize {
509 const template = "{value}";505 const i = Diagnostics.templateIndex(w, fmt, "{value}");
510 const i = std.mem.indexOf(u8, fmt, template).?;
511 try w.writeAll(fmt[0..i]);
512
513 switch (res.val.opt_ref) {506 switch (res.val.opt_ref) {
514 .none => try w.writeAll("(none)"),507 .none => try w.writeAll("(none)"),
515 .null => try w.writeAll("nullptr_t"),508 .null => try w.writeAll("nullptr_t"),
...@@ -521,8 +514,7 @@ fn formatResult(p: *Parser, w: *std.Io.Writer, fmt: []const u8, res: Result) !us...@@ -521,8 +514,7 @@ fn formatResult(p: *Parser, w: *std.Io.Writer, fmt: []const u8, res: Result) !us
521 },514 },
522 },515 },
523 }516 }
524517 return i;
525 return i + template.len;
526}518}
527519
528const Normalized = struct {520const Normalized = struct {
...@@ -532,10 +524,8 @@ const Normalized = struct {...@@ -532,10 +524,8 @@ const Normalized = struct {
532 return .{ .str = str };524 return .{ .str = str };
533 }525 }
534526
535 pub fn format(ctx: Normalized, w: *std.Io.Writer, fmt_str: []const u8) !usize {527 pub fn format(ctx: Normalized, w: *std.Io.Writer, fmt: []const u8) !usize {
536 const template = "{normalized}";528 const i = Diagnostics.templateIndex(w, fmt, "{normalized}");
537 const i = std.mem.indexOf(u8, fmt_str, template).?;
538 try w.writeAll(fmt_str[0..i]);
539 var it: std.unicode.Utf8Iterator = .{529 var it: std.unicode.Utf8Iterator = .{
540 .bytes = ctx.str,530 .bytes = ctx.str,
541 .i = 0,531 .i = 0,
...@@ -557,7 +547,7 @@ const Normalized = struct {...@@ -557,7 +547,7 @@ const Normalized = struct {
557 });547 });
558 }548 }
559 }549 }
560 return i + template.len;550 return i;
561 }551 }
562};552};
563553
...@@ -568,12 +558,10 @@ const Codepoint = struct {...@@ -568,12 +558,10 @@ const Codepoint = struct {
568 return .{ .codepoint = codepoint };558 return .{ .codepoint = codepoint };
569 }559 }
570560
571 pub fn format(ctx: Codepoint, w: *std.Io.Writer, fmt_str: []const u8) !usize {561 pub fn format(ctx: Codepoint, w: *std.Io.Writer, fmt: []const u8) !usize {
572 const template = "{codepoint}";562 const i = Diagnostics.templateIndex(w, fmt, "{codepoint}");
573 const i = std.mem.indexOf(u8, fmt_str, template).?;
574 try w.writeAll(fmt_str[0..i]);
575 try w.print("{X:0>4}", .{ctx.codepoint});563 try w.print("{X:0>4}", .{ctx.codepoint});
576 return i + template.len;564 return i;
577 }565 }
578};566};
579567
...@@ -584,12 +572,10 @@ const Escaped = struct {...@@ -584,12 +572,10 @@ const Escaped = struct {
584 return .{ .str = str };572 return .{ .str = str };
585 }573 }
586574
587 pub fn format(ctx: Escaped, w: *std.Io.Writer, fmt_str: []const u8) !usize {575 pub fn format(ctx: Escaped, w: *std.Io.Writer, fmt: []const u8) !usize {
588 const template = "{s}";576 const i = Diagnostics.templateIndex(w, fmt, "{s}");
589 const i = std.mem.indexOf(u8, fmt_str, template).?;
590 try w.writeAll(fmt_str[0..i]);
591 try std.zig.stringEscape(ctx.str, w);577 try std.zig.stringEscape(ctx.str, w);
592 return i + template.len;578 return i;
593 }579 }
594};580};
595581
...@@ -626,11 +612,11 @@ pub fn errValueChanged(p: *Parser, tok_i: TokenIndex, diagnostic: Diagnostic, re...@@ -626,11 +612,11 @@ pub fn errValueChanged(p: *Parser, tok_i: TokenIndex, diagnostic: Diagnostic, re
626fn checkDeprecatedUnavailable(p: *Parser, ty: QualType, usage_tok: TokenIndex, decl_tok: TokenIndex) !void {612fn checkDeprecatedUnavailable(p: *Parser, ty: QualType, usage_tok: TokenIndex, decl_tok: TokenIndex) !void {
627 if (ty.getAttribute(p.comp, .@"error")) |@"error"| {613 if (ty.getAttribute(p.comp, .@"error")) |@"error"| {
628 const msg_str = p.comp.interner.get(@"error".msg.ref()).bytes;614 const msg_str = p.comp.interner.get(@"error".msg.ref()).bytes;
629 try p.err(usage_tok, .error_attribute, .{ p.tokSlice(@"error".__name_tok), std.zig.fmtString(msg_str) });615 try p.err(usage_tok, .error_attribute, .{ p.tokSlice(@"error".__name_tok), Escaped.init(msg_str) });
630 }616 }
631 if (ty.getAttribute(p.comp, .warning)) |warning| {617 if (ty.getAttribute(p.comp, .warning)) |warning| {
632 const msg_str = p.comp.interner.get(warning.msg.ref()).bytes;618 const msg_str = p.comp.interner.get(warning.msg.ref()).bytes;
633 try p.err(usage_tok, .warning_attribute, .{ p.tokSlice(warning.__name_tok), std.zig.fmtString(msg_str) });619 try p.err(usage_tok, .warning_attribute, .{ p.tokSlice(warning.__name_tok), Escaped.init(msg_str) });
634 }620 }
635 if (ty.getAttribute(p.comp, .unavailable)) |unavailable| {621 if (ty.getAttribute(p.comp, .unavailable)) |unavailable| {
636 try p.errDeprecated(usage_tok, .unavailable, unavailable.msg);622 try p.errDeprecated(usage_tok, .unavailable, unavailable.msg);
...@@ -4734,7 +4720,7 @@ fn asmOperand(p: *Parser, names: *std.ArrayList(?TokenIndex), constraints: *Node...@@ -4734,7 +4720,7 @@ fn asmOperand(p: *Parser, names: *std.ArrayList(?TokenIndex), constraints: *Node
4734 try constraints.append(gpa, constraint.node);4720 try constraints.append(gpa, constraint.node);
47354721
4736 const l_paren = p.eatToken(.l_paren) orelse {4722 const l_paren = p.eatToken(.l_paren) orelse {
4737 try p.err(p.tok_i, .expected_token, .{ p.tok_ids[p.tok_i], .l_paren });4723 try p.err(p.tok_i, .expected_token, .{ p.tok_ids[p.tok_i], Token.Id.l_paren });
4738 return error.ParsingFailed;4724 return error.ParsingFailed;
4739 };4725 };
4740 const maybe_res = try p.expr();4726 const maybe_res = try p.expr();
...@@ -10221,12 +10207,30 @@ test "Node locations" {...@@ -10221,12 +10207,30 @@ test "Node locations" {
10221 try std.testing.expectEqual(0, comp.diagnostics.total);10207 try std.testing.expectEqual(0, comp.diagnostics.total);
10222 for (tree.root_decls.items[tree.root_decls.items.len - 3 ..], 0..) |node, i| {10208 for (tree.root_decls.items[tree.root_decls.items.len - 3 ..], 0..) |node, i| {
10223 const slice = tree.tokSlice(node.tok(&tree));10209 const slice = tree.tokSlice(node.tok(&tree));
10224 const expected = switch (i) {10210 const expected_slice = switch (i) {
10225 0 => "foo",10211 0 => "foo",
10226 1 => "bar",10212 1 => "bar",
10227 2 => "main",10213 2 => "main",
10228 else => unreachable,10214 else => unreachable,
10229 };10215 };
10230 try std.testing.expectEqualStrings(expected, slice);10216 try std.testing.expectEqualStrings(expected_slice, slice);
10217
10218 const loc = node.loc(&tree).expand(&comp);
10219 const expected_col: u32 = switch (i) {
10220 0 => 5,
10221 1 => 5,
10222 2 => 5,
10223 else => unreachable,
10224 };
10225 try std.testing.expectEqual(expected_col, loc.col);
10226
10227 const expected_line_no = i + 1;
10228 try std.testing.expectEqual(expected_line_no, loc.line_no);
10229
10230 const expected_source_path = "file.c";
10231 try std.testing.expectEqualStrings(expected_source_path, loc.path);
10232
10233 const expected_source_kind = Source.Kind.user;
10234 try std.testing.expectEqual(expected_source_kind, loc.kind);
10231 }10235 }
10232}10236}
lib/compiler/aro/aro/Preprocessor.zig+4-1
...@@ -1703,7 +1703,10 @@ fn expandFuncMacro(...@@ -1703,7 +1703,10 @@ fn expandFuncMacro(
1703 else1703 else
1704 &[1]TokenWithExpansionLocs{tokFromRaw(raw_next)},1704 &[1]TokenWithExpansionLocs{tokFromRaw(raw_next)},
1705 .macro_param, .macro_param_no_expand => getPasteArgs(args.items[raw_next.end]),1705 .macro_param, .macro_param_no_expand => getPasteArgs(args.items[raw_next.end]),
1706 .keyword_va_args => variable_arguments.items,1706 .keyword_va_args => if (variable_arguments.items.len == 0) blk: {
1707 try pp.err(raw_next, .no_argument_variadic_macro, .{});
1708 break :blk &[1]TokenWithExpansionLocs{.{ .id = .placemarker, .loc = .{ .id = .generated } }};
1709 } else variable_arguments.items,
1707 .keyword_va_opt => blk: {1710 .keyword_va_opt => blk: {
1708 try pp.expandVaOpt(&va_opt_buf, raw_next, variable_arguments.items.len != 0);1711 try pp.expandVaOpt(&va_opt_buf, raw_next, variable_arguments.items.len != 0);
1709 if (va_opt_buf.items.len == 0) break;1712 if (va_opt_buf.items.len == 0) break;
lib/compiler/aro/aro/Preprocessor/Diagnostic.zig+7
...@@ -449,3 +449,10 @@ pub const date_time: Diagnostic = .{...@@ -449,3 +449,10 @@ pub const date_time: Diagnostic = .{
449 .opt = .@"date-time",449 .opt = .@"date-time",
450 .show_in_system_headers = true,450 .show_in_system_headers = true,
451};451};
452
453pub const no_argument_variadic_macro: Diagnostic = .{
454 .fmt = "passing no argument for the '...' parameter of a variadic macro is incompatible with C standards before C23",
455 .opt = .@"variadic-macro-arguments-omitted",
456 .kind = .off,
457 .extension = true,
458};
lib/compiler/aro/aro/Tree.zig+2-2
...@@ -1699,9 +1699,9 @@ pub const Node = union(enum) {...@@ -1699,9 +1699,9 @@ pub const Node = union(enum) {
1699 return tree.nodes.items(.tok)[@intFromEnum(index)];1699 return tree.nodes.items(.tok)[@intFromEnum(index)];
1700 }1700 }
17011701
1702 pub fn loc(index: Index, tree: *const Tree) ?Source.Location {1702 pub fn loc(index: Index, tree: *const Tree) Source.Location {
1703 const tok_i = index.tok(tree);1703 const tok_i = index.tok(tree);
1704 return tree.tokens.items(.loc)[@intFromEnum(tok_i)];1704 return tree.tokens.items(.loc)[tok_i];
1705 }1705 }
17061706
1707 pub fn qt(index: Index, tree: *const Tree) QualType {1707 pub fn qt(index: Index, tree: *const Tree) QualType {
lib/compiler/aro/aro/target.zig+3-1
...@@ -681,10 +681,12 @@ pub fn toLLVMTriple(target: std.Target, buf: []u8) []const u8 {...@@ -681,10 +681,12 @@ pub fn toLLVMTriple(target: std.Target, buf: []u8) []const u8 {
681 .driverkit => "driverkit",681 .driverkit => "driverkit",
682 .visionos => "xros",682 .visionos => "xros",
683 .serenity => "serenity",683 .serenity => "serenity",
684 .vulkan => "vulkan",
684 .managarm => "managarm",685 .managarm => "managarm",
686 .@"3ds",
687 .vita,
685 .opencl,688 .opencl,
686 .opengl,689 .opengl,
687 .vulkan,
688 .plan9,690 .plan9,
689 .other,691 .other,
690 => "unknown",692 => "unknown",
lib/compiler/aro/aro/text_literal.zig+4-7
...@@ -154,17 +154,14 @@ pub const Ascii = struct {...@@ -154,17 +154,14 @@ pub const Ascii = struct {
154 return .{ .val = @intCast(val) };154 return .{ .val = @intCast(val) };
155 }155 }
156156
157 pub fn format(ctx: Ascii, w: *std.Io.Writer, fmt_str: []const u8) !usize {157 pub fn format(ctx: Ascii, w: *std.Io.Writer, fmt: []const u8) !usize {
158 const template = "{c}";158 const i = Diagnostics.templateIndex(w, fmt, "{c}");
159 const i = std.mem.indexOf(u8, fmt_str, template).?;
160 try w.writeAll(fmt_str[0..i]);
161
162 if (std.ascii.isPrint(ctx.val)) {159 if (std.ascii.isPrint(ctx.val)) {
163 try w.writeByte(ctx.val);160 try w.writeByte(ctx.val);
164 } else {161 } else {
165 try w.print("x{x:0>2}", .{ctx.val});162 try w.print("x{x:0>2}", .{ctx.val});
166 }163 }
167 return i + template.len;164 return i;
168 }165 }
169};166};
170167
...@@ -345,7 +342,7 @@ pub const Parser = struct {...@@ -345,7 +342,7 @@ pub const Parser = struct {
345 else => switch (@typeInfo(@TypeOf(arg))) {342 else => switch (@typeInfo(@TypeOf(arg))) {
346 .int, .comptime_int => try Diagnostics.formatInt(w, fmt[i..], arg),343 .int, .comptime_int => try Diagnostics.formatInt(w, fmt[i..], arg),
347 .pointer => try Diagnostics.formatString(w, fmt[i..], arg),344 .pointer => try Diagnostics.formatString(w, fmt[i..], arg),
348 else => unreachable,345 else => comptime unreachable,
349 },346 },
350 };347 };
351 }348 }
lib/compiler/translate-c/MacroTranslator.zig+59-52
...@@ -175,8 +175,10 @@ pub fn transMacro(mt: *MacroTranslator) ParseError!void {...@@ -175,8 +175,10 @@ pub fn transMacro(mt: *MacroTranslator) ParseError!void {
175}175}
176176
177fn createMacroFn(mt: *MacroTranslator, name: []const u8, ref: ZigNode, proto_alias: *ast.Payload.Func) !ZigNode {177fn createMacroFn(mt: *MacroTranslator, name: []const u8, ref: ZigNode, proto_alias: *ast.Payload.Func) !ZigNode {
178 var fn_params = std.array_list.Managed(ast.Payload.Param).init(mt.t.gpa);178 const gpa = mt.t.gpa;
179 defer fn_params.deinit();179 const arena = mt.t.arena;
180 var fn_params: std.ArrayList(ast.Payload.Param) = .empty;
181 defer fn_params.deinit(gpa);
180182
181 var block_scope = try Scope.Block.init(mt.t, &mt.t.global_scope.base, false);183 var block_scope = try Scope.Block.init(mt.t, &mt.t.global_scope.base, false);
182 defer block_scope.deinit();184 defer block_scope.deinit();
...@@ -184,7 +186,7 @@ fn createMacroFn(mt: *MacroTranslator, name: []const u8, ref: ZigNode, proto_ali...@@ -184,7 +186,7 @@ fn createMacroFn(mt: *MacroTranslator, name: []const u8, ref: ZigNode, proto_ali
184 for (proto_alias.data.params) |param| {186 for (proto_alias.data.params) |param| {
185 const param_name = try block_scope.makeMangledName(param.name orelse "arg");187 const param_name = try block_scope.makeMangledName(param.name orelse "arg");
186188
187 try fn_params.append(.{189 try fn_params.append(gpa, .{
188 .name = param_name,190 .name = param_name,
189 .type = param.type,191 .type = param.type,
190 .is_noalias = param.is_noalias,192 .is_noalias = param.is_noalias,
...@@ -198,27 +200,28 @@ fn createMacroFn(mt: *MacroTranslator, name: []const u8, ref: ZigNode, proto_ali...@@ -198,27 +200,28 @@ fn createMacroFn(mt: *MacroTranslator, name: []const u8, ref: ZigNode, proto_ali
198 else200 else
199 unreachable;201 unreachable;
200202
201 const unwrap_expr = try ZigTag.unwrap.create(mt.t.arena, init);203 const unwrap_expr = try ZigTag.unwrap.create(arena, init);
202 const args = try mt.t.arena.alloc(ZigNode, fn_params.items.len);204 const args = try arena.alloc(ZigNode, fn_params.items.len);
203 for (fn_params.items, 0..) |param, i| {205 for (fn_params.items, 0..) |param, i| {
204 args[i] = try ZigTag.identifier.create(mt.t.arena, param.name.?);206 args[i] = try ZigTag.identifier.create(arena, param.name.?);
205 }207 }
206 const call_expr = try ZigTag.call.create(mt.t.arena, .{208 const call_expr = try ZigTag.call.create(arena, .{
207 .lhs = unwrap_expr,209 .lhs = unwrap_expr,
208 .args = args,210 .args = args,
209 });211 });
210 const return_expr = try ZigTag.@"return".create(mt.t.arena, call_expr);212 const return_expr = try ZigTag.@"return".create(arena, call_expr);
211 const block = try ZigTag.block_single.create(mt.t.arena, return_expr);213 const block = try ZigTag.block_single.create(arena, return_expr);
212214
213 return ZigTag.pub_inline_fn.create(mt.t.arena, .{215 return ZigTag.pub_inline_fn.create(arena, .{
214 .name = name,216 .name = name,
215 .params = try mt.t.arena.dupe(ast.Payload.Param, fn_params.items),217 .params = try arena.dupe(ast.Payload.Param, fn_params.items),
216 .return_type = proto_alias.data.return_type,218 .return_type = proto_alias.data.return_type,
217 .body = block,219 .body = block,
218 });220 });
219}221}
220222
221fn parseCExpr(mt: *MacroTranslator, scope: *Scope) ParseError!ZigNode {223fn parseCExpr(mt: *MacroTranslator, scope: *Scope) ParseError!ZigNode {
224 const arena = mt.t.arena;
222 // TODO parseCAssignExpr here225 // TODO parseCAssignExpr here
223 var block_scope = try Scope.Block.init(mt.t, scope, true);226 var block_scope = try Scope.Block.init(mt.t, scope, true);
224 defer block_scope.deinit();227 defer block_scope.deinit();
...@@ -229,14 +232,14 @@ fn parseCExpr(mt: *MacroTranslator, scope: *Scope) ParseError!ZigNode {...@@ -229,14 +232,14 @@ fn parseCExpr(mt: *MacroTranslator, scope: *Scope) ParseError!ZigNode {
229 var last = node;232 var last = node;
230 while (true) {233 while (true) {
231 // suppress result234 // suppress result
232 const ignore = try ZigTag.discard.create(mt.t.arena, .{ .should_skip = false, .value = last });235 const ignore = try ZigTag.discard.create(arena, .{ .should_skip = false, .value = last });
233 try block_scope.statements.append(mt.t.gpa, ignore);236 try block_scope.statements.append(mt.t.gpa, ignore);
234237
235 last = try mt.parseCCondExpr(&block_scope.base);238 last = try mt.parseCCondExpr(&block_scope.base);
236 if (!mt.eat(.comma)) break;239 if (!mt.eat(.comma)) break;
237 }240 }
238241
239 const break_node = try ZigTag.break_val.create(mt.t.arena, .{242 const break_node = try ZigTag.break_val.create(arena, .{
240 .label = block_scope.label,243 .label = block_scope.label,
241 .val = last,244 .val = last,
242 });245 });
...@@ -245,10 +248,11 @@ fn parseCExpr(mt: *MacroTranslator, scope: *Scope) ParseError!ZigNode {...@@ -245,10 +248,11 @@ fn parseCExpr(mt: *MacroTranslator, scope: *Scope) ParseError!ZigNode {
245}248}
246249
247fn parseCNumLit(mt: *MacroTranslator) ParseError!ZigNode {250fn parseCNumLit(mt: *MacroTranslator) ParseError!ZigNode {
251 const arena = mt.t.arena;
248 const lit_bytes = mt.tokSlice();252 const lit_bytes = mt.tokSlice();
249 mt.i += 1;253 mt.i += 1;
250254
251 var bytes = try std.ArrayListUnmanaged(u8).initCapacity(mt.t.arena, lit_bytes.len + 3);255 var bytes = try std.ArrayListUnmanaged(u8).initCapacity(arena, lit_bytes.len + 3);
252256
253 const prefix = aro.Tree.Token.NumberPrefix.fromString(lit_bytes);257 const prefix = aro.Tree.Token.NumberPrefix.fromString(lit_bytes);
254 switch (prefix) {258 switch (prefix) {
...@@ -330,7 +334,7 @@ fn parseCNumLit(mt: *MacroTranslator) ParseError!ZigNode {...@@ -330,7 +334,7 @@ fn parseCNumLit(mt: *MacroTranslator) ParseError!ZigNode {
330 }334 }
331335
332 if (is_float) {336 if (is_float) {
333 const type_node = try ZigTag.type.create(mt.t.arena, switch (suffix) {337 const type_node = try ZigTag.type.create(arena, switch (suffix) {
334 .F16 => "f16",338 .F16 => "f16",
335 .F => "f32",339 .F => "f32",
336 .None => "f64",340 .None => "f64",
...@@ -339,10 +343,10 @@ fn parseCNumLit(mt: *MacroTranslator) ParseError!ZigNode {...@@ -339,10 +343,10 @@ fn parseCNumLit(mt: *MacroTranslator) ParseError!ZigNode {
339 .Q, .F128 => "f128",343 .Q, .F128 => "f128",
340 else => unreachable,344 else => unreachable,
341 });345 });
342 const rhs = try ZigTag.float_literal.create(mt.t.arena, bytes.items);346 const rhs = try ZigTag.float_literal.create(arena, bytes.items);
343 return ZigTag.as.create(mt.t.arena, .{ .lhs = type_node, .rhs = rhs });347 return ZigTag.as.create(arena, .{ .lhs = type_node, .rhs = rhs });
344 } else {348 } else {
345 const type_node = try ZigTag.type.create(mt.t.arena, switch (suffix) {349 const type_node = try ZigTag.type.create(arena, switch (suffix) {
346 .None => "c_int",350 .None => "c_int",
347 .U => "c_uint",351 .U => "c_uint",
348 .L => "c_long",352 .L => "c_long",
...@@ -365,11 +369,11 @@ fn parseCNumLit(mt: *MacroTranslator) ParseError!ZigNode {...@@ -365,11 +369,11 @@ fn parseCNumLit(mt: *MacroTranslator) ParseError!ZigNode {
365 else => unreachable,369 else => unreachable,
366 };370 };
367371
368 const literal_node = try ZigTag.integer_literal.create(mt.t.arena, bytes.items);372 const literal_node = try ZigTag.integer_literal.create(arena, bytes.items);
369 if (guaranteed_to_fit) {373 if (guaranteed_to_fit) {
370 return ZigTag.as.create(mt.t.arena, .{ .lhs = type_node, .rhs = literal_node });374 return ZigTag.as.create(arena, .{ .lhs = type_node, .rhs = literal_node });
371 } else {375 } else {
372 return mt.t.createHelperCallNode(.promoteIntLiteral, &.{ type_node, literal_node, try ZigTag.enum_literal.create(mt.t.arena, @tagName(prefix)) });376 return mt.t.createHelperCallNode(.promoteIntLiteral, &.{ type_node, literal_node, try ZigTag.enum_literal.create(arena, @tagName(prefix)) });
373 }377 }
374 }378 }
375}379}
...@@ -563,6 +567,7 @@ fn escapeUnprintables(mt: *MacroTranslator) ![]const u8 {...@@ -563,6 +567,7 @@ fn escapeUnprintables(mt: *MacroTranslator) ![]const u8 {
563}567}
564568
565fn parseCPrimaryExpr(mt: *MacroTranslator, scope: *Scope) ParseError!ZigNode {569fn parseCPrimaryExpr(mt: *MacroTranslator, scope: *Scope) ParseError!ZigNode {
570 const arena = mt.t.arena;
566 const tok = mt.peek();571 const tok = mt.peek();
567 switch (tok) {572 switch (tok) {
568 .char_literal,573 .char_literal,
...@@ -573,12 +578,12 @@ fn parseCPrimaryExpr(mt: *MacroTranslator, scope: *Scope) ParseError!ZigNode {...@@ -573,12 +578,12 @@ fn parseCPrimaryExpr(mt: *MacroTranslator, scope: *Scope) ParseError!ZigNode {
573 => {578 => {
574 const slice = mt.tokSlice();579 const slice = mt.tokSlice();
575 if (slice[0] != '\'' or slice[1] == '\\' or slice.len == 3) {580 if (slice[0] != '\'' or slice[1] == '\\' or slice.len == 3) {
576 return ZigTag.char_literal.create(mt.t.arena, try mt.escapeUnprintables());581 return ZigTag.char_literal.create(arena, try mt.escapeUnprintables());
577 } else {582 } else {
578 mt.i += 1;583 mt.i += 1;
579584
580 const str = try std.fmt.allocPrint(mt.t.arena, "0x{x}", .{slice[1 .. slice.len - 1]});585 const str = try std.fmt.allocPrint(arena, "0x{x}", .{slice[1 .. slice.len - 1]});
581 return ZigTag.integer_literal.create(mt.t.arena, str);586 return ZigTag.integer_literal.create(arena, str);
582 }587 }
583 },588 },
584 .string_literal,589 .string_literal,
...@@ -586,7 +591,7 @@ fn parseCPrimaryExpr(mt: *MacroTranslator, scope: *Scope) ParseError!ZigNode {...@@ -586,7 +591,7 @@ fn parseCPrimaryExpr(mt: *MacroTranslator, scope: *Scope) ParseError!ZigNode {
586 .string_literal_utf_8,591 .string_literal_utf_8,
587 .string_literal_utf_32,592 .string_literal_utf_32,
588 .string_literal_wide,593 .string_literal_wide,
589 => return ZigTag.string_literal.create(mt.t.arena, try mt.escapeUnprintables()),594 => return ZigTag.string_literal.create(arena, try mt.escapeUnprintables()),
590 .pp_num => return mt.parseCNumLit(),595 .pp_num => return mt.parseCNumLit(),
591 .l_paren => {596 .l_paren => {
592 mt.i += 1;597 mt.i += 1;
...@@ -600,7 +605,7 @@ fn parseCPrimaryExpr(mt: *MacroTranslator, scope: *Scope) ParseError!ZigNode {...@@ -600,7 +605,7 @@ fn parseCPrimaryExpr(mt: *MacroTranslator, scope: *Scope) ParseError!ZigNode {
600 mt.i += 1;605 mt.i += 1;
601606
602 const mangled_name = scope.getAlias(param) orelse param;607 const mangled_name = scope.getAlias(param) orelse param;
603 return try ZigTag.identifier.create(mt.t.arena, mangled_name);608 return try ZigTag.identifier.create(arena, mangled_name);
604 },609 },
605 .identifier, .extended_identifier => {610 .identifier, .extended_identifier => {
606 const slice = mt.tokSlice();611 const slice = mt.tokSlice();
...@@ -608,17 +613,17 @@ fn parseCPrimaryExpr(mt: *MacroTranslator, scope: *Scope) ParseError!ZigNode {...@@ -608,17 +613,17 @@ fn parseCPrimaryExpr(mt: *MacroTranslator, scope: *Scope) ParseError!ZigNode {
608613
609 const mangled_name = scope.getAlias(slice) orelse slice;614 const mangled_name = scope.getAlias(slice) orelse slice;
610 if (Translator.builtin_typedef_map.get(mangled_name)) |ty| {615 if (Translator.builtin_typedef_map.get(mangled_name)) |ty| {
611 return ZigTag.type.create(mt.t.arena, ty);616 return ZigTag.type.create(arena, ty);
612 }617 }
613 if (builtins.map.get(mangled_name)) |builtin| {618 if (builtins.map.get(mangled_name)) |builtin| {
614 const builtin_identifier = try ZigTag.identifier.create(mt.t.arena, "__builtin");619 const builtin_identifier = try ZigTag.identifier.create(arena, "__builtin");
615 return ZigTag.field_access.create(mt.t.arena, .{620 return ZigTag.field_access.create(arena, .{
616 .lhs = builtin_identifier,621 .lhs = builtin_identifier,
617 .field_name = builtin.name,622 .field_name = builtin.name,
618 });623 });
619 }624 }
620625
621 const identifier = try ZigTag.identifier.create(mt.t.arena, mangled_name);626 const identifier = try ZigTag.identifier.create(arena, mangled_name);
622 scope.skipVariableDiscard(mangled_name);627 scope.skipVariableDiscard(mangled_name);
623 refs_var: {628 refs_var: {
624 const ident_node = mt.t.global_scope.sym_table.get(slice) orelse break :refs_var;629 const ident_node = mt.t.global_scope.sym_table.get(slice) orelse break :refs_var;
...@@ -1114,6 +1119,8 @@ fn parseCPostfixExpr(mt: *MacroTranslator, scope: *Scope, type_name: ?ZigNode) P...@@ -1114,6 +1119,8 @@ fn parseCPostfixExpr(mt: *MacroTranslator, scope: *Scope, type_name: ?ZigNode) P
1114}1119}
11151120
1116fn parseCPostfixExprInner(mt: *MacroTranslator, scope: *Scope, type_name: ?ZigNode) ParseError!ZigNode {1121fn parseCPostfixExprInner(mt: *MacroTranslator, scope: *Scope, type_name: ?ZigNode) ParseError!ZigNode {
1122 const gpa = mt.t.gpa;
1123 const arena = mt.t.arena;
1117 var node = type_name orelse try mt.parseCPrimaryExpr(scope);1124 var node = type_name orelse try mt.parseCPrimaryExpr(scope);
1118 while (true) {1125 while (true) {
1119 switch (mt.peek()) {1126 switch (mt.peek()) {
...@@ -1122,39 +1129,39 @@ fn parseCPostfixExprInner(mt: *MacroTranslator, scope: *Scope, type_name: ?ZigNo...@@ -1122,39 +1129,39 @@ fn parseCPostfixExprInner(mt: *MacroTranslator, scope: *Scope, type_name: ?ZigNo
1122 const field_name = mt.tokSlice();1129 const field_name = mt.tokSlice();
1123 try mt.expect(.identifier);1130 try mt.expect(.identifier);
11241131
1125 node = try ZigTag.field_access.create(mt.t.arena, .{ .lhs = node, .field_name = field_name });1132 node = try ZigTag.field_access.create(arena, .{ .lhs = node, .field_name = field_name });
1126 },1133 },
1127 .arrow => {1134 .arrow => {
1128 mt.i += 1;1135 mt.i += 1;
1129 const field_name = mt.tokSlice();1136 const field_name = mt.tokSlice();
1130 try mt.expect(.identifier);1137 try mt.expect(.identifier);
11311138
1132 const deref = try ZigTag.deref.create(mt.t.arena, node);1139 const deref = try ZigTag.deref.create(arena, node);
1133 node = try ZigTag.field_access.create(mt.t.arena, .{ .lhs = deref, .field_name = field_name });1140 node = try ZigTag.field_access.create(arena, .{ .lhs = deref, .field_name = field_name });
1134 },1141 },
1135 .l_bracket => {1142 .l_bracket => {
1136 mt.i += 1;1143 mt.i += 1;
11371144
1138 const index_val = try mt.macroIntFromBool(try mt.parseCExpr(scope));1145 const index_val = try mt.macroIntFromBool(try mt.parseCExpr(scope));
1139 const index = try ZigTag.as.create(mt.t.arena, .{1146 const index = try ZigTag.as.create(arena, .{
1140 .lhs = try ZigTag.type.create(mt.t.arena, "usize"),1147 .lhs = try ZigTag.type.create(arena, "usize"),
1141 .rhs = try ZigTag.int_cast.create(mt.t.arena, index_val),1148 .rhs = try ZigTag.int_cast.create(arena, index_val),
1142 });1149 });
1143 node = try ZigTag.array_access.create(mt.t.arena, .{ .lhs = node, .rhs = index });1150 node = try ZigTag.array_access.create(arena, .{ .lhs = node, .rhs = index });
1144 try mt.expect(.r_bracket);1151 try mt.expect(.r_bracket);
1145 },1152 },
1146 .l_paren => {1153 .l_paren => {
1147 mt.i += 1;1154 mt.i += 1;
11481155
1149 if (mt.eat(.r_paren)) {1156 if (mt.eat(.r_paren)) {
1150 node = try ZigTag.call.create(mt.t.arena, .{ .lhs = node, .args = &.{} });1157 node = try ZigTag.call.create(arena, .{ .lhs = node, .args = &.{} });
1151 } else {1158 } else {
1152 var args = std.array_list.Managed(ZigNode).init(mt.t.gpa);1159 var args: std.ArrayList(ZigNode) = .empty;
1153 defer args.deinit();1160 defer args.deinit(gpa);
11541161
1155 while (true) {1162 while (true) {
1156 const arg = try mt.parseCCondExpr(scope);1163 const arg = try mt.parseCCondExpr(scope);
1157 try args.append(arg);1164 try args.append(gpa, arg);
11581165
1159 const next_id = mt.peek();1166 const next_id = mt.peek();
1160 switch (next_id) {1167 switch (next_id) {
...@@ -1171,7 +1178,7 @@ fn parseCPostfixExprInner(mt: *MacroTranslator, scope: *Scope, type_name: ?ZigNo...@@ -1171,7 +1178,7 @@ fn parseCPostfixExprInner(mt: *MacroTranslator, scope: *Scope, type_name: ?ZigNo
1171 },1178 },
1172 }1179 }
1173 }1180 }
1174 node = try ZigTag.call.create(mt.t.arena, .{ .lhs = node, .args = try mt.t.arena.dupe(ZigNode, args.items) });1181 node = try ZigTag.call.create(arena, .{ .lhs = node, .args = try arena.dupe(ZigNode, args.items) });
1175 }1182 }
1176 },1183 },
1177 .l_brace => {1184 .l_brace => {
...@@ -1179,8 +1186,8 @@ fn parseCPostfixExprInner(mt: *MacroTranslator, scope: *Scope, type_name: ?ZigNo...@@ -1179,8 +1186,8 @@ fn parseCPostfixExprInner(mt: *MacroTranslator, scope: *Scope, type_name: ?ZigNo
11791186
1180 // Check for designated field initializers1187 // Check for designated field initializers
1181 if (mt.peek() == .period) {1188 if (mt.peek() == .period) {
1182 var init_vals = std.array_list.Managed(ast.Payload.ContainerInitDot.Initializer).init(mt.t.gpa);1189 var init_vals: std.ArrayList(ast.Payload.ContainerInitDot.Initializer) = .empty;
1183 defer init_vals.deinit();1190 defer init_vals.deinit(gpa);
11841191
1185 while (true) {1192 while (true) {
1186 try mt.expect(.period);1193 try mt.expect(.period);
...@@ -1189,7 +1196,7 @@ fn parseCPostfixExprInner(mt: *MacroTranslator, scope: *Scope, type_name: ?ZigNo...@@ -1189,7 +1196,7 @@ fn parseCPostfixExprInner(mt: *MacroTranslator, scope: *Scope, type_name: ?ZigNo
1189 try mt.expect(.equal);1196 try mt.expect(.equal);
11901197
1191 const val = try mt.parseCCondExpr(scope);1198 const val = try mt.parseCCondExpr(scope);
1192 try init_vals.append(.{ .name = name, .value = val });1199 try init_vals.append(gpa, .{ .name = name, .value = val });
11931200
1194 const next_id = mt.peek();1201 const next_id = mt.peek();
1195 switch (next_id) {1202 switch (next_id) {
...@@ -1206,17 +1213,17 @@ fn parseCPostfixExprInner(mt: *MacroTranslator, scope: *Scope, type_name: ?ZigNo...@@ -1206,17 +1213,17 @@ fn parseCPostfixExprInner(mt: *MacroTranslator, scope: *Scope, type_name: ?ZigNo
1206 },1213 },
1207 }1214 }
1208 }1215 }
1209 const tuple_node = try ZigTag.container_init_dot.create(mt.t.arena, try mt.t.arena.dupe(ast.Payload.ContainerInitDot.Initializer, init_vals.items));1216 const tuple_node = try ZigTag.container_init_dot.create(arena, try arena.dupe(ast.Payload.ContainerInitDot.Initializer, init_vals.items));
1210 node = try ZigTag.std_mem_zeroinit.create(mt.t.arena, .{ .lhs = node, .rhs = tuple_node });1217 node = try ZigTag.std_mem_zeroinit.create(arena, .{ .lhs = node, .rhs = tuple_node });
1211 continue;1218 continue;
1212 }1219 }
12131220
1214 var init_vals = std.array_list.Managed(ZigNode).init(mt.t.gpa);1221 var init_vals: std.ArrayList(ZigNode) = .empty;
1215 defer init_vals.deinit();1222 defer init_vals.deinit(gpa);
12161223
1217 while (true) {1224 while (true) {
1218 const val = try mt.parseCCondExpr(scope);1225 const val = try mt.parseCCondExpr(scope);
1219 try init_vals.append(val);1226 try init_vals.append(gpa, val);
12201227
1221 const next_id = mt.peek();1228 const next_id = mt.peek();
1222 switch (next_id) {1229 switch (next_id) {
...@@ -1233,8 +1240,8 @@ fn parseCPostfixExprInner(mt: *MacroTranslator, scope: *Scope, type_name: ?ZigNo...@@ -1233,8 +1240,8 @@ fn parseCPostfixExprInner(mt: *MacroTranslator, scope: *Scope, type_name: ?ZigNo
1233 },1240 },
1234 }1241 }
1235 }1242 }
1236 const tuple_node = try ZigTag.tuple.create(mt.t.arena, try mt.t.arena.dupe(ZigNode, init_vals.items));1243 const tuple_node = try ZigTag.tuple.create(arena, try arena.dupe(ZigNode, init_vals.items));
1237 node = try ZigTag.std_mem_zeroinit.create(mt.t.arena, .{ .lhs = node, .rhs = tuple_node });1244 node = try ZigTag.std_mem_zeroinit.create(arena, .{ .lhs = node, .rhs = tuple_node });
1238 },1245 },
1239 .plus_plus, .minus_minus => {1246 .plus_plus, .minus_minus => {
1240 try mt.fail("TODO postfix inc/dec expr", .{});1247 try mt.fail("TODO postfix inc/dec expr", .{});
lib/compiler/translate-c/PatternList.zig+10-10
...@@ -91,11 +91,11 @@ const Pattern = struct {...@@ -91,11 +91,11 @@ const Pattern = struct {
91 fn init(pl: *Pattern, allocator: mem.Allocator, template: Template) Error!void {91 fn init(pl: *Pattern, allocator: mem.Allocator, template: Template) Error!void {
92 const source = template[0];92 const source = template[0];
93 const impl = template[1];93 const impl = template[1];
94 var tok_list = std.array_list.Managed(CToken).init(allocator);94 var tok_list: std.ArrayList(CToken) = .empty;
95 defer tok_list.deinit();95 defer tok_list.deinit(allocator);
9696
97 pl.* = .{97 pl.* = .{
98 .slicer = try tokenizeMacro(source, &tok_list),98 .slicer = try tokenizeMacro(allocator, source, &tok_list),
99 .impl = impl,99 .impl = impl,
100 };100 };
101 }101 }
...@@ -170,7 +170,7 @@ pub fn match(pl: PatternList, ms: MacroSlicer) Error!?Impl {...@@ -170,7 +170,7 @@ pub fn match(pl: PatternList, ms: MacroSlicer) Error!?Impl {
170 return null;170 return null;
171}171}
172172
173fn tokenizeMacro(source: []const u8, tok_list: *std.array_list.Managed(CToken)) Error!MacroSlicer {173fn tokenizeMacro(allocator: mem.Allocator, source: []const u8, tok_list: *std.ArrayList(CToken)) Error!MacroSlicer {
174 var param_count: u32 = 0;174 var param_count: u32 = 0;
175 var param_buf: [8][]const u8 = undefined;175 var param_buf: [8][]const u8 = undefined;
176176
...@@ -207,7 +207,7 @@ fn tokenizeMacro(source: []const u8, tok_list: *std.array_list.Managed(CToken))...@@ -207,7 +207,7 @@ fn tokenizeMacro(source: []const u8, tok_list: *std.array_list.Managed(CToken))
207 const slice = source[tok.start..tok.end];207 const slice = source[tok.start..tok.end];
208 for (param_buf[0..param_count], 0..) |param, i| {208 for (param_buf[0..param_count], 0..) |param, i| {
209 if (std.mem.eql(u8, param, slice)) {209 if (std.mem.eql(u8, param, slice)) {
210 try tok_list.append(.{210 try tok_list.append(allocator, .{
211 .id = .macro_param,211 .id = .macro_param,
212 .source = .unused,212 .source = .unused,
213 .end = @intCast(i),213 .end = @intCast(i),
...@@ -224,12 +224,12 @@ fn tokenizeMacro(source: []const u8, tok_list: *std.array_list.Managed(CToken))...@@ -224,12 +224,12 @@ fn tokenizeMacro(source: []const u8, tok_list: *std.array_list.Managed(CToken))
224 .nl, .eof => break,224 .nl, .eof => break,
225 else => {},225 else => {},
226 }226 }
227 try tok_list.append(tok);227 try tok_list.append(allocator, tok);
228 }228 }
229229
230 return .{230 return .{
231 .source = source,231 .source = source,
232 .tokens = try tok_list.toOwnedSlice(),232 .tokens = try tok_list.toOwnedSlice(allocator),
233 .params = param_count,233 .params = param_count,
234 };234 };
235}235}
...@@ -243,9 +243,9 @@ test "Macro matching" {...@@ -243,9 +243,9 @@ test "Macro matching" {
243 source: []const u8,243 source: []const u8,
244 comptime expected_match: ?Impl,244 comptime expected_match: ?Impl,
245 ) !void {245 ) !void {
246 var tok_list = std.array_list.Managed(CToken).init(allocator);246 var tok_list: std.ArrayList(CToken) = .empty;
247 defer tok_list.deinit();247 defer tok_list.deinit(allocator);
248 const ms = try tokenizeMacro(source, &tok_list);248 const ms = try tokenizeMacro(allocator, source, &tok_list);
249 defer allocator.free(ms.tokens);249 defer allocator.free(ms.tokens);
250250
251 const matched = try pattern_list.match(ms);251 const matched = try pattern_list.match(ms);
lib/compiler/translate-c/Translator.zig+26-25
...@@ -216,10 +216,10 @@ pub fn translate(options: Options) mem.Allocator.Error![]u8 {...@@ -216,10 +216,10 @@ pub fn translate(options: Options) mem.Allocator.Error![]u8 {
216216
217 try translator.global_scope.processContainerMemberFns();217 try translator.global_scope.processContainerMemberFns();
218218
219 var aw: std.Io.Writer.Allocating = .init(gpa);219 var allocating: std.Io.Writer.Allocating = .init(gpa);
220 defer aw.deinit();220 defer allocating.deinit();
221221
222 aw.writer.writeAll(222 allocating.writer.writeAll(
223 \\pub const __builtin = @import("std").zig.c_translation.builtins;223 \\pub const __builtin = @import("std").zig.c_translation.builtins;
224 \\pub const __helpers = @import("std").zig.c_translation.helpers;224 \\pub const __helpers = @import("std").zig.c_translation.helpers;
225 \\225 \\
...@@ -231,8 +231,8 @@ pub fn translate(options: Options) mem.Allocator.Error![]u8 {...@@ -231,8 +231,8 @@ pub fn translate(options: Options) mem.Allocator.Error![]u8 {
231 gpa.free(zig_ast.source);231 gpa.free(zig_ast.source);
232 zig_ast.deinit(gpa);232 zig_ast.deinit(gpa);
233 }233 }
234 zig_ast.render(gpa, &aw.writer, .{}) catch return error.OutOfMemory;234 zig_ast.render(gpa, &allocating.writer, .{}) catch return error.OutOfMemory;
235 return aw.toOwnedSlice();235 return allocating.toOwnedSlice();
236}236}
237237
238fn prepopulateGlobalNameTable(t: *Translator) !void {238fn prepopulateGlobalNameTable(t: *Translator) !void {
...@@ -489,11 +489,12 @@ fn transRecordDecl(t: *Translator, scope: *Scope, record_qt: QualType) Error!voi...@@ -489,11 +489,12 @@ fn transRecordDecl(t: *Translator, scope: *Scope, record_qt: QualType) Error!voi
489 break :init ZigTag.opaque_literal.init();489 break :init ZigTag.opaque_literal.init();
490 }490 }
491491
492 var fields = try std.array_list.Managed(ast.Payload.Container.Field).initCapacity(t.gpa, record_ty.fields.len);492 var fields: std.ArrayList(ast.Payload.Container.Field) = .empty;
493 defer fields.deinit();493 defer fields.deinit(t.gpa);
494 try fields.ensureUnusedCapacity(t.gpa, record_ty.fields.len);
494495
495 var functions = std.array_list.Managed(ZigNode).init(t.gpa);496 var functions: std.ArrayList(ZigNode) = .empty;
496 defer functions.deinit();497 defer functions.deinit(t.gpa);
497498
498 var unnamed_field_count: u32 = 0;499 var unnamed_field_count: u32 = 0;
499500
...@@ -558,7 +559,7 @@ fn transRecordDecl(t: *Translator, scope: *Scope, record_qt: QualType) Error!voi...@@ -558,7 +559,7 @@ fn transRecordDecl(t: *Translator, scope: *Scope, record_qt: QualType) Error!voi
558 field_name = try std.fmt.allocPrint(t.arena, "_{s}", .{field_name});559 field_name = try std.fmt.allocPrint(t.arena, "_{s}", .{field_name});
559560
560 const member = try t.createFlexibleMemberFn(member_name, field_name);561 const member = try t.createFlexibleMemberFn(member_name, field_name);
561 try functions.append(member);562 try functions.append(t.gpa, member);
562563
563 break :field_type zero_array;564 break :field_type zero_array;
564 }565 }
...@@ -600,7 +601,7 @@ fn transRecordDecl(t: *Translator, scope: *Scope, record_qt: QualType) Error!voi...@@ -600,7 +601,7 @@ fn transRecordDecl(t: *Translator, scope: *Scope, record_qt: QualType) Error!voi
600 const padding_bits = record_ty.layout.?.size_bits;601 const padding_bits = record_ty.layout.?.size_bits;
601 const alignment_bits = record_ty.layout.?.field_alignment_bits;602 const alignment_bits = record_ty.layout.?.field_alignment_bits;
602603
603 try fields.append(.{604 try fields.append(t.gpa, .{
604 .name = "_padding",605 .name = "_padding",
605 .type = try ZigTag.type.create(t.arena, try std.fmt.allocPrint(t.arena, "u{d}", .{padding_bits})),606 .type = try ZigTag.type.create(t.arena, try std.fmt.allocPrint(t.arena, "u{d}", .{padding_bits})),
606 .alignment = @divExact(alignment_bits, 8),607 .alignment = @divExact(alignment_bits, 8),
...@@ -1789,8 +1790,8 @@ fn transSwitch(t: *Translator, scope: *Scope, switch_stmt: Node.SwitchStmt) Tran...@@ -1789,8 +1790,8 @@ fn transSwitch(t: *Translator, scope: *Scope, switch_stmt: Node.SwitchStmt) Tran
1789 defer cond_scope.deinit();1790 defer cond_scope.deinit();
1790 const switch_expr = try t.transExpr(&cond_scope.base, switch_stmt.cond, .used);1791 const switch_expr = try t.transExpr(&cond_scope.base, switch_stmt.cond, .used);
17911792
1792 var cases = std.array_list.Managed(ZigNode).init(t.gpa);1793 var cases: std.ArrayList(ZigNode) = .empty;
1793 defer cases.deinit();1794 defer cases.deinit(t.gpa);
1794 var has_default = false;1795 var has_default = false;
17951796
1796 const body_node = switch_stmt.body.get(t.tree);1797 const body_node = switch_stmt.body.get(t.tree);
...@@ -1803,21 +1804,21 @@ fn transSwitch(t: *Translator, scope: *Scope, switch_stmt: Node.SwitchStmt) Tran...@@ -1803,21 +1804,21 @@ fn transSwitch(t: *Translator, scope: *Scope, switch_stmt: Node.SwitchStmt) Tran
1803 for (body, 0..) |stmt, i| {1804 for (body, 0..) |stmt, i| {
1804 switch (stmt.get(t.tree)) {1805 switch (stmt.get(t.tree)) {
1805 .case_stmt => {1806 .case_stmt => {
1806 var items = std.array_list.Managed(ZigNode).init(t.gpa);1807 var items: std.ArrayList(ZigNode) = .empty;
1807 defer items.deinit();1808 defer items.deinit(t.gpa);
1808 const sub = try t.transCaseStmt(base_scope, stmt, &items);1809 const sub = try t.transCaseStmt(base_scope, stmt, &items);
1809 const res = try t.transSwitchProngStmt(base_scope, sub, body[i..]);1810 const res = try t.transSwitchProngStmt(base_scope, sub, body[i..]);
18101811
1811 if (items.items.len == 0) {1812 if (items.items.len == 0) {
1812 has_default = true;1813 has_default = true;
1813 const switch_else = try ZigTag.switch_else.create(t.arena, res);1814 const switch_else = try ZigTag.switch_else.create(t.arena, res);
1814 try cases.append(switch_else);1815 try cases.append(t.gpa, switch_else);
1815 } else {1816 } else {
1816 const switch_prong = try ZigTag.switch_prong.create(t.arena, .{1817 const switch_prong = try ZigTag.switch_prong.create(t.arena, .{
1817 .cases = try t.arena.dupe(ZigNode, items.items),1818 .cases = try t.arena.dupe(ZigNode, items.items),
1818 .cond = res,1819 .cond = res,
1819 });1820 });
1820 try cases.append(switch_prong);1821 try cases.append(t.gpa, switch_prong);
1821 }1822 }
1822 },1823 },
1823 .default_stmt => |default_stmt| {1824 .default_stmt => |default_stmt| {
...@@ -1833,7 +1834,7 @@ fn transSwitch(t: *Translator, scope: *Scope, switch_stmt: Node.SwitchStmt) Tran...@@ -1833,7 +1834,7 @@ fn transSwitch(t: *Translator, scope: *Scope, switch_stmt: Node.SwitchStmt) Tran
1833 const res = try t.transSwitchProngStmt(base_scope, sub, body[i..]);1834 const res = try t.transSwitchProngStmt(base_scope, sub, body[i..]);
18341835
1835 const switch_else = try ZigTag.switch_else.create(t.arena, res);1836 const switch_else = try ZigTag.switch_else.create(t.arena, res);
1836 try cases.append(switch_else);1837 try cases.append(t.gpa, switch_else);
1837 },1838 },
1838 else => {}, // collected in transSwitchProngStmt1839 else => {}, // collected in transSwitchProngStmt
1839 }1840 }
...@@ -1841,7 +1842,7 @@ fn transSwitch(t: *Translator, scope: *Scope, switch_stmt: Node.SwitchStmt) Tran...@@ -1841,7 +1842,7 @@ fn transSwitch(t: *Translator, scope: *Scope, switch_stmt: Node.SwitchStmt) Tran
18411842
1842 if (!has_default) {1843 if (!has_default) {
1843 const else_prong = try ZigTag.switch_else.create(t.arena, ZigTag.empty_block.init());1844 const else_prong = try ZigTag.switch_else.create(t.arena, ZigTag.empty_block.init());
1844 try cases.append(else_prong);1845 try cases.append(t.gpa, else_prong);
1845 }1846 }
18461847
1847 const switch_node = try ZigTag.@"switch".create(t.arena, .{1848 const switch_node = try ZigTag.@"switch".create(t.arena, .{
...@@ -1861,7 +1862,7 @@ fn transCaseStmt(...@@ -1861,7 +1862,7 @@ fn transCaseStmt(
1861 t: *Translator,1862 t: *Translator,
1862 scope: *Scope,1863 scope: *Scope,
1863 stmt: Node.Index,1864 stmt: Node.Index,
1864 items: *std.array_list.Managed(ZigNode),1865 items: *std.ArrayList(ZigNode),
1865) TransError!Node.Index {1866) TransError!Node.Index {
1866 var sub = stmt;1867 var sub = stmt;
1867 var seen_default = false;1868 var seen_default = false;
...@@ -1886,7 +1887,7 @@ fn transCaseStmt(...@@ -1886,7 +1887,7 @@ fn transCaseStmt(
1886 break :blk try ZigTag.ellipsis3.create(t.arena, .{ .lhs = start_node, .rhs = end_node });1887 break :blk try ZigTag.ellipsis3.create(t.arena, .{ .lhs = start_node, .rhs = end_node });
1887 } else try t.transExpr(scope, case_stmt.start, .used);1888 } else try t.transExpr(scope, case_stmt.start, .used);
18881889
1889 try items.append(expr);1890 try items.append(t.gpa, expr);
1890 sub = case_stmt.body;1891 sub = case_stmt.body;
1891 },1892 },
1892 else => return sub,1893 else => return sub,
...@@ -3873,7 +3874,7 @@ fn createNumberNode(t: *Translator, num: anytype, num_kind: enum { int, float })...@@ -3873,7 +3874,7 @@ fn createNumberNode(t: *Translator, num: anytype, num_kind: enum { int, float })
38733874
3874fn createCharLiteralNode(t: *Translator, narrow: bool, val: u32) TransError!ZigNode {3875fn createCharLiteralNode(t: *Translator, narrow: bool, val: u32) TransError!ZigNode {
3875 return ZigTag.char_literal.create(t.arena, if (narrow)3876 return ZigTag.char_literal.create(t.arena, if (narrow)
3876 try std.fmt.allocPrint(t.arena, "'{f}'", .{std.zig.fmtChar(@intCast(val))})3877 try std.fmt.allocPrint(t.arena, "'{f}'", .{std.zig.fmtChar(@as(u8, @intCast(val)))})
3877 else3878 else
3878 try std.fmt.allocPrint(t.arena, "'\\u{{{x}}}'", .{val}));3879 try std.fmt.allocPrint(t.arena, "'\\u{{{x}}}'", .{val}));
3879}3880}
...@@ -3986,8 +3987,8 @@ fn createFlexibleMemberFn(...@@ -3986,8 +3987,8 @@ fn createFlexibleMemberFn(
3986// =================3987// =================
39873988
3988fn transMacros(t: *Translator) !void {3989fn transMacros(t: *Translator) !void {
3989 var tok_list = std.array_list.Managed(CToken).init(t.gpa);3990 var tok_list: std.ArrayList(CToken) = .empty;
3990 defer tok_list.deinit();3991 defer tok_list.deinit(t.gpa);
39913992
3992 var pattern_list = try PatternList.init(t.gpa);3993 var pattern_list = try PatternList.init(t.gpa);
3993 defer pattern_list.deinit(t.gpa);3994 defer pattern_list.deinit(t.gpa);
...@@ -3999,7 +4000,7 @@ fn transMacros(t: *Translator) !void {...@@ -3999,7 +4000,7 @@ fn transMacros(t: *Translator) !void {
3999 }4000 }
40004001
4001 tok_list.items.len = 0;4002 tok_list.items.len = 0;
4002 try tok_list.ensureUnusedCapacity(macro.tokens.len);4003 try tok_list.ensureUnusedCapacity(t.gpa, macro.tokens.len);
4003 for (macro.tokens) |tok| {4004 for (macro.tokens) |tok| {
4004 switch (tok.id) {4005 switch (tok.id) {
4005 .invalid => continue,4006 .invalid => continue,
lib/compiler/translate-c/ast.zig+23-23
...@@ -798,9 +798,8 @@ pub const Payload = struct {...@@ -798,9 +798,8 @@ pub const Payload = struct {
798pub fn render(gpa: Allocator, nodes: []const Node) !std.zig.Ast {798pub fn render(gpa: Allocator, nodes: []const Node) !std.zig.Ast {
799 var ctx: Context = .{799 var ctx: Context = .{
800 .gpa = gpa,800 .gpa = gpa,
801 .buf = std.array_list.Managed(u8).init(gpa),
802 };801 };
803 defer ctx.buf.deinit();802 defer ctx.buf.deinit(gpa);
804 defer ctx.nodes.deinit(gpa);803 defer ctx.nodes.deinit(gpa);
805 defer ctx.extra_data.deinit(gpa);804 defer ctx.extra_data.deinit(gpa);
806 defer ctx.tokens.deinit(gpa);805 defer ctx.tokens.deinit(gpa);
...@@ -813,7 +812,7 @@ pub fn render(gpa: Allocator, nodes: []const Node) !std.zig.Ast {...@@ -813,7 +812,7 @@ pub fn render(gpa: Allocator, nodes: []const Node) !std.zig.Ast {
813 try ctx.tokens.ensureTotalCapacity(gpa, estimated_tokens_count);812 try ctx.tokens.ensureTotalCapacity(gpa, estimated_tokens_count);
814 // Estimate that each each token is 3 bytes long.813 // Estimate that each each token is 3 bytes long.
815 const estimated_buf_len = estimated_tokens_count * 3;814 const estimated_buf_len = estimated_tokens_count * 3;
816 try ctx.buf.ensureTotalCapacity(estimated_buf_len);815 try ctx.buf.ensureTotalCapacity(gpa, estimated_buf_len);
817816
818 ctx.nodes.appendAssumeCapacity(.{817 ctx.nodes.appendAssumeCapacity(.{
819 .tag = .root,818 .tag = .root,
...@@ -822,12 +821,12 @@ pub fn render(gpa: Allocator, nodes: []const Node) !std.zig.Ast {...@@ -822,12 +821,12 @@ pub fn render(gpa: Allocator, nodes: []const Node) !std.zig.Ast {
822 });821 });
823822
824 const root_members = blk: {823 const root_members = blk: {
825 var result = std.array_list.Managed(NodeIndex).init(gpa);824 var result: std.ArrayList(NodeIndex) = .empty;
826 defer result.deinit();825 defer result.deinit(gpa);
827826
828 for (nodes) |node| {827 for (nodes) |node| {
829 const res = (try renderNodeOpt(&ctx, node)) orelse continue;828 const res = (try renderNodeOpt(&ctx, node)) orelse continue;
830 try result.append(res);829 try result.append(gpa, res);
831 }830 }
832 break :blk try ctx.listToSpan(result.items);831 break :blk try ctx.listToSpan(result.items);
833 };832 };
...@@ -843,7 +842,7 @@ pub fn render(gpa: Allocator, nodes: []const Node) !std.zig.Ast {...@@ -843,7 +842,7 @@ pub fn render(gpa: Allocator, nodes: []const Node) !std.zig.Ast {
843 });842 });
844843
845 return .{844 return .{
846 .source = try ctx.buf.toOwnedSliceSentinel(0),845 .source = try ctx.buf.toOwnedSliceSentinel(gpa, 0),
847 .tokens = ctx.tokens.toOwnedSlice(),846 .tokens = ctx.tokens.toOwnedSlice(),
848 .nodes = ctx.nodes.toOwnedSlice(),847 .nodes = ctx.nodes.toOwnedSlice(),
849 .extra_data = try ctx.extra_data.toOwnedSlice(gpa),848 .extra_data = try ctx.extra_data.toOwnedSlice(gpa),
...@@ -859,14 +858,14 @@ const TokenTag = std.zig.Token.Tag;...@@ -859,14 +858,14 @@ const TokenTag = std.zig.Token.Tag;
859858
860const Context = struct {859const Context = struct {
861 gpa: Allocator,860 gpa: Allocator,
862 buf: std.array_list.Managed(u8),861 buf: std.ArrayList(u8) = .empty,
863 nodes: std.zig.Ast.NodeList = .{},862 nodes: std.zig.Ast.NodeList = .empty,
864 extra_data: std.ArrayListUnmanaged(u32) = .empty,863 extra_data: std.ArrayListUnmanaged(u32) = .empty,
865 tokens: std.zig.Ast.TokenList = .{},864 tokens: std.zig.Ast.TokenList = .empty,
866865
867 fn addTokenFmt(c: *Context, tag: TokenTag, comptime format: []const u8, args: anytype) Allocator.Error!TokenIndex {866 fn addTokenFmt(c: *Context, tag: TokenTag, comptime format: []const u8, args: anytype) Allocator.Error!TokenIndex {
868 const start_index = c.buf.items.len;867 const start_index = c.buf.items.len;
869 try c.buf.print(format ++ " ", args);868 try c.buf.print(c.gpa, format ++ " ", args);
870869
871 try c.tokens.append(c.gpa, .{870 try c.tokens.append(c.gpa, .{
872 .tag = tag,871 .tag = tag,
...@@ -925,8 +924,8 @@ fn renderNodeOpt(c: *Context, node: Node) Allocator.Error!?NodeIndex {...@@ -925,8 +924,8 @@ fn renderNodeOpt(c: *Context, node: Node) Allocator.Error!?NodeIndex {
925 switch (node.tag()) {924 switch (node.tag()) {
926 .warning => {925 .warning => {
927 const payload = node.castTag(.warning).?.data;926 const payload = node.castTag(.warning).?.data;
928 try c.buf.appendSlice(payload);927 try c.buf.appendSlice(c.gpa, payload);
929 try c.buf.append('\n');928 try c.buf.append(c.gpa, '\n');
930 return null;929 return null;
931 },930 },
932 .discard => {931 .discard => {
...@@ -1687,12 +1686,12 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -1687,12 +1686,12 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
1687 }1686 }
1688 const l_brace = try c.addToken(.l_brace, "{");1687 const l_brace = try c.addToken(.l_brace, "{");
16891688
1690 var stmts = std.array_list.Managed(NodeIndex).init(c.gpa);1689 var stmts: std.ArrayList(NodeIndex) = .empty;
1691 defer stmts.deinit();1690 defer stmts.deinit(c.gpa);
1692 for (payload.stmts) |stmt| {1691 for (payload.stmts) |stmt| {
1693 const res = (try renderNodeOpt(c, stmt)) orelse continue;1692 const res = (try renderNodeOpt(c, stmt)) orelse continue;
1694 try addSemicolonIfNeeded(c, stmt);1693 try addSemicolonIfNeeded(c, stmt);
1695 try stmts.append(res);1694 try stmts.append(c.gpa, res);
1696 }1695 }
1697 const span = try c.listToSpan(stmts.items);1696 const span = try c.listToSpan(stmts.items);
1698 _ = try c.addToken(.r_brace, "}");1697 _ = try c.addToken(.r_brace, "}");
...@@ -2830,8 +2829,8 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {...@@ -2830,8 +2829,8 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {
2830 const fn_token = try c.addToken(.keyword_fn, "fn");2829 const fn_token = try c.addToken(.keyword_fn, "fn");
2831 if (payload.name) |some| _ = try c.addIdentifier(some);2830 if (payload.name) |some| _ = try c.addIdentifier(some);
28322831
2833 const params = try renderParams(c, payload.params, payload.is_var_args);2832 var params = try renderParams(c, payload.params, payload.is_var_args);
2834 defer params.deinit();2833 defer params.deinit(c.gpa);
2835 var span: NodeSubRange = undefined;2834 var span: NodeSubRange = undefined;
2836 if (params.items.len > 1) span = try c.listToSpan(params.items);2835 if (params.items.len > 1) span = try c.listToSpan(params.items);
28372836
...@@ -2998,8 +2997,8 @@ fn renderMacroFunc(c: *Context, node: Node) !NodeIndex {...@@ -2998,8 +2997,8 @@ fn renderMacroFunc(c: *Context, node: Node) !NodeIndex {
2998 const fn_token = try c.addToken(.keyword_fn, "fn");2997 const fn_token = try c.addToken(.keyword_fn, "fn");
2999 _ = try c.addIdentifier(payload.name);2998 _ = try c.addIdentifier(payload.name);
30002999
3001 const params = try renderParams(c, payload.params, false);3000 var params = try renderParams(c, payload.params, false);
3002 defer params.deinit();3001 defer params.deinit(c.gpa);
3003 var span: NodeSubRange = undefined;3002 var span: NodeSubRange = undefined;
3004 if (params.items.len > 1) span = try c.listToSpan(params.items);3003 if (params.items.len > 1) span = try c.listToSpan(params.items);
30053004
...@@ -3035,10 +3034,11 @@ fn renderMacroFunc(c: *Context, node: Node) !NodeIndex {...@@ -3035,10 +3034,11 @@ fn renderMacroFunc(c: *Context, node: Node) !NodeIndex {
3035 });3034 });
3036}3035}
30373036
3038fn renderParams(c: *Context, params: []Payload.Param, is_var_args: bool) !std.array_list.Managed(NodeIndex) {3037fn renderParams(c: *Context, params: []Payload.Param, is_var_args: bool) !std.ArrayList(NodeIndex) {
3039 _ = try c.addToken(.l_paren, "(");3038 _ = try c.addToken(.l_paren, "(");
3040 var rendered = try std.array_list.Managed(NodeIndex).initCapacity(c.gpa, @max(params.len, 1));3039 var rendered: std.ArrayList(NodeIndex) = .empty;
3041 errdefer rendered.deinit();3040 errdefer rendered.deinit(c.gpa);
3041 try rendered.ensureUnusedCapacity(c.gpa, @max(params.len, 1));
30423042
3043 for (params, 0..) |param, i| {3043 for (params, 0..) |param, i| {
3044 if (i != 0) _ = try c.addToken(.comma, ",");3044 if (i != 0) _ = try c.addToken(.comma, ",");
lib/compiler/translate-c/main.zig+6-4
...@@ -110,7 +110,7 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8) !void {...@@ -110,7 +110,7 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8) !void {
110 defer macro_buf.deinit(gpa);110 defer macro_buf.deinit(gpa);
111111
112 var discard_buf: [256]u8 = undefined;112 var discard_buf: [256]u8 = undefined;
113 var discarding: std.io.Writer.Discarding = .init(&discard_buf);113 var discarding: std.Io.Writer.Discarding = .init(&discard_buf);
114 assert(!try d.parseArgs(&discarding.writer, &macro_buf, aro_args));114 assert(!try d.parseArgs(&discarding.writer, &macro_buf, aro_args));
115 if (macro_buf.items.len > std.math.maxInt(u32)) {115 if (macro_buf.items.len > std.math.maxInt(u32)) {
116 return d.fatal("user provided macro source exceeded max size", .{});116 return d.fatal("user provided macro source exceeded max size", .{});
...@@ -206,9 +206,11 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8) !void {...@@ -206,9 +206,11 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8) !void {
206 out_file_path = path;206 out_file_path = path;
207 }207 }
208208
209 var out_writer = out_file.writer(&.{});209 var out_writer = out_file.writer(&out_buf);
210 out_writer.interface.writeAll(rendered_zig) catch210 out_writer.interface.writeAll(rendered_zig) catch {};
211 return d.fatal("failed to write result to '{s}': {s}", .{ out_file_path, aro.Driver.errorDescription(out_writer.err.?) });211 out_writer.interface.flush() catch {};
212 if (out_writer.err) |write_err|
213 return d.fatal("failed to write result to '{s}': {s}", .{ out_file_path, aro.Driver.errorDescription(write_err) });
212214
213 if (fast_exit) process.exit(0);215 if (fast_exit) process.exit(0);
214}216}