mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
update aro & translate-c
This commit is contained in:
parent
e05073b9e4
commit
d83c76eb5a
7
lib/compiler/aro/aro/Attribute.zig
vendored
7
lib/compiler/aro/aro/Attribute.zig
vendored
@ -792,12 +792,7 @@ pub fn normalize(name: []const u8) []const u8 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn ignoredAttrErr(p: *Parser, tok: TokenIndex, attr: Attribute.Tag, context: []const u8) !void {
|
fn ignoredAttrErr(p: *Parser, tok: TokenIndex, attr: Attribute.Tag, context: []const u8) !void {
|
||||||
const strings_top = p.strings.items.len;
|
try p.err(tok, .ignored_attribute, .{ @tagName(attr), context });
|
||||||
defer p.strings.items.len = strings_top;
|
|
||||||
|
|
||||||
try p.strings.print("attribute '{s}' ignored on {s}", .{ @tagName(attr), context });
|
|
||||||
const str = try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
|
|
||||||
try p.errStr(.ignored_attribute, tok, str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn applyParameterAttributes(p: *Parser, qt: QualType, attr_buf_start: usize, diagnostic: ?Parser.Diagnostic) !QualType {
|
pub fn applyParameterAttributes(p: *Parser, qt: QualType, attr_buf_start: usize, diagnostic: ?Parser.Diagnostic) !QualType {
|
||||||
|
|||||||
57
lib/compiler/aro/aro/Compilation.zig
vendored
57
lib/compiler/aro/aro/Compilation.zig
vendored
@ -132,6 +132,8 @@ sources: std.StringArrayHashMapUnmanaged(Source) = .empty,
|
|||||||
/// Allocated into `gpa`, but keys are externally managed.
|
/// Allocated into `gpa`, but keys are externally managed.
|
||||||
include_dirs: std.ArrayList([]const u8) = .empty,
|
include_dirs: std.ArrayList([]const u8) = .empty,
|
||||||
/// Allocated into `gpa`, but keys are externally managed.
|
/// Allocated into `gpa`, but keys are externally managed.
|
||||||
|
iquote_include_dirs: std.ArrayList([]const u8) = .empty,
|
||||||
|
/// Allocated into `gpa`, but keys are externally managed.
|
||||||
system_include_dirs: std.ArrayList([]const u8) = .empty,
|
system_include_dirs: std.ArrayList([]const u8) = .empty,
|
||||||
/// Allocated into `gpa`, but keys are externally managed.
|
/// Allocated into `gpa`, but keys are externally managed.
|
||||||
after_include_dirs: std.ArrayList([]const u8) = .empty,
|
after_include_dirs: std.ArrayList([]const u8) = .empty,
|
||||||
@ -192,6 +194,7 @@ pub fn deinit(comp: *Compilation) void {
|
|||||||
}
|
}
|
||||||
comp.sources.deinit(gpa);
|
comp.sources.deinit(gpa);
|
||||||
comp.include_dirs.deinit(gpa);
|
comp.include_dirs.deinit(gpa);
|
||||||
|
comp.iquote_include_dirs.deinit(gpa);
|
||||||
comp.system_include_dirs.deinit(gpa);
|
comp.system_include_dirs.deinit(gpa);
|
||||||
comp.after_include_dirs.deinit(gpa);
|
comp.after_include_dirs.deinit(gpa);
|
||||||
comp.framework_dirs.deinit(gpa);
|
comp.framework_dirs.deinit(gpa);
|
||||||
@ -240,12 +243,26 @@ fn generateSystemDefines(comp: *Compilation, w: *std.Io.Writer) !void {
|
|||||||
const ptr_width = comp.target.ptrBitWidth();
|
const ptr_width = comp.target.ptrBitWidth();
|
||||||
const is_gnu = comp.langopts.standard.isGNU();
|
const is_gnu = comp.langopts.standard.isGNU();
|
||||||
|
|
||||||
if (comp.langopts.gnuc_version > 0) {
|
const gnuc_version = comp.langopts.gnuc_version orelse comp.langopts.emulate.defaultGccVersion();
|
||||||
try w.print("#define __GNUC__ {d}\n", .{comp.langopts.gnuc_version / 10_000});
|
if (gnuc_version > 0) {
|
||||||
try w.print("#define __GNUC_MINOR__ {d}\n", .{comp.langopts.gnuc_version / 100 % 100});
|
try w.print("#define __GNUC__ {d}\n", .{gnuc_version / 10_000});
|
||||||
try w.print("#define __GNUC_PATCHLEVEL__ {d}\n", .{comp.langopts.gnuc_version % 100});
|
try w.print("#define __GNUC_MINOR__ {d}\n", .{gnuc_version / 100 % 100});
|
||||||
|
try w.print("#define __GNUC_PATCHLEVEL__ {d}\n", .{gnuc_version % 100});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try w.writeAll(
|
||||||
|
\\#define __ARO_EMULATE_CLANG__ 1
|
||||||
|
\\#define __ARO_EMULATE_GCC__ 2
|
||||||
|
\\#define __ARO_EMULATE_MSVC__ 3
|
||||||
|
\\
|
||||||
|
);
|
||||||
|
const emulated = switch (comp.langopts.emulate) {
|
||||||
|
.clang => "__ARO_EMULATE_CLANG__",
|
||||||
|
.gcc => "__ARO_EMULATE_GCC__",
|
||||||
|
.msvc => "__ARO_EMULATE_MSVC__",
|
||||||
|
};
|
||||||
|
try w.print("#define __ARO_EMULATE__ {s}\n", .{emulated});
|
||||||
|
|
||||||
if (comp.code_gen_options.optimization_level.hasAnyOptimizations()) {
|
if (comp.code_gen_options.optimization_level.hasAnyOptimizations()) {
|
||||||
try define(w, "__OPTIMIZE__");
|
try define(w, "__OPTIMIZE__");
|
||||||
}
|
}
|
||||||
@ -330,6 +347,8 @@ fn generateSystemDefines(comp: *Compilation, w: *std.Io.Writer) !void {
|
|||||||
=> try define(w, "__APPLE__"),
|
=> try define(w, "__APPLE__"),
|
||||||
.wasi => try define(w, "__wasi__"),
|
.wasi => try define(w, "__wasi__"),
|
||||||
.emscripten => try define(w, "__EMSCRIPTEN__"),
|
.emscripten => try define(w, "__EMSCRIPTEN__"),
|
||||||
|
.@"3ds" => try define(w, "__3DS__"),
|
||||||
|
.vita => try define(w, "__vita__"),
|
||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -431,10 +450,13 @@ fn generateSystemDefines(comp: *Compilation, w: *std.Io.Writer) !void {
|
|||||||
.{ .f16c, "__F16C__" },
|
.{ .f16c, "__F16C__" },
|
||||||
.{ .gfni, "__GFNI__" },
|
.{ .gfni, "__GFNI__" },
|
||||||
.{ .evex512, "__EVEX512__" },
|
.{ .evex512, "__EVEX512__" },
|
||||||
.{ .avx10_1_256, "__AVX10_1__" },
|
|
||||||
.{ .avx10_1_512, "__AVX10_1_512__" },
|
.{ .avx10_1, "__AVX10_1__" },
|
||||||
.{ .avx10_2_256, "__AVX10_2__" },
|
.{ .avx10_1, "__AVX10_1_512__" },
|
||||||
.{ .avx10_2_512, "__AVX10_2_512__" },
|
|
||||||
|
.{ .avx10_2, "__AVX10_2__" },
|
||||||
|
.{ .avx10_2, "__AVX10_2_512__" },
|
||||||
|
|
||||||
.{ .avx512cd, "__AVX512CD__" },
|
.{ .avx512cd, "__AVX512CD__" },
|
||||||
.{ .avx512vpopcntdq, "__AVX512VPOPCNTDQ__" },
|
.{ .avx512vpopcntdq, "__AVX512VPOPCNTDQ__" },
|
||||||
.{ .avx512vnni, "__AVX512VNNI__" },
|
.{ .avx512vnni, "__AVX512VNNI__" },
|
||||||
@ -935,7 +957,7 @@ fn generateSystemDefines(comp: *Compilation, w: *std.Io.Writer) !void {
|
|||||||
pub fn generateBuiltinMacros(comp: *Compilation, system_defines_mode: SystemDefinesMode) AddSourceError!Source {
|
pub fn generateBuiltinMacros(comp: *Compilation, system_defines_mode: SystemDefinesMode) AddSourceError!Source {
|
||||||
try comp.type_store.initNamedTypes(comp);
|
try comp.type_store.initNamedTypes(comp);
|
||||||
|
|
||||||
var allocating: std.io.Writer.Allocating = try .initCapacity(comp.gpa, 2 << 13);
|
var allocating: std.Io.Writer.Allocating = try .initCapacity(comp.gpa, 2 << 13);
|
||||||
defer allocating.deinit();
|
defer allocating.deinit();
|
||||||
|
|
||||||
comp.writeBuiltinMacros(system_defines_mode, &allocating.writer) catch |err| switch (err) {
|
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:
|
|||||||
try w.print("#define __{s}_WIDTH__ {d}\n", .{ name, qt.sizeof(comp) * 8 });
|
try w.print("#define __{s}_WIDTH__ {d}\n", .{ name, qt.sizeof(comp) * 8 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn generateIntMaxAndWidth(comp: *Compilation, w: *std.Io.Writer, name: []const u8, qt: QualType) !void {
|
||||||
|
try comp.generateIntMax(w, name, qt);
|
||||||
|
try comp.generateIntWidth(w, name, qt);
|
||||||
|
}
|
||||||
|
|
||||||
fn generateSizeofType(comp: *Compilation, w: *std.Io.Writer, name: []const u8, qt: QualType) !void {
|
fn generateSizeofType(comp: *Compilation, w: *std.Io.Writer, name: []const u8, qt: QualType) !void {
|
||||||
try w.print("#define {s} {d}\n", .{ name, qt.sizeof(comp) });
|
try w.print("#define {s} {d}\n", .{ name, qt.sizeof(comp) });
|
||||||
}
|
}
|
||||||
@ -1597,7 +1624,7 @@ pub fn hasInclude(
|
|||||||
which: WhichInclude,
|
which: WhichInclude,
|
||||||
opt_dep_file: ?*DepFile,
|
opt_dep_file: ?*DepFile,
|
||||||
) Compilation.Error!bool {
|
) Compilation.Error!bool {
|
||||||
if (try FindInclude.run(comp, filename, switch (which) {
|
if (try FindInclude.run(comp, filename, include_type, switch (which) {
|
||||||
.next => .{ .only_search_after_dir = comp.getSource(includer_token_source).path },
|
.next => .{ .only_search_after_dir = comp.getSource(includer_token_source).path },
|
||||||
.first => switch (include_type) {
|
.first => switch (include_type) {
|
||||||
.quotes => .{ .allow_same_dir = comp.getSource(includer_token_source).path },
|
.quotes => .{ .allow_same_dir = comp.getSource(includer_token_source).path },
|
||||||
@ -1629,6 +1656,7 @@ const FindInclude = struct {
|
|||||||
fn run(
|
fn run(
|
||||||
comp: *Compilation,
|
comp: *Compilation,
|
||||||
include_path: []const u8,
|
include_path: []const u8,
|
||||||
|
include_type: IncludeType,
|
||||||
search_strat: union(enum) {
|
search_strat: union(enum) {
|
||||||
allow_same_dir: []const u8,
|
allow_same_dir: []const u8,
|
||||||
only_search,
|
only_search,
|
||||||
@ -1663,7 +1691,12 @@ const FindInclude = struct {
|
|||||||
find.wait_for = std.fs.path.dirname(other_file);
|
find.wait_for = std.fs.path.dirname(other_file);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
switch (include_type) {
|
||||||
|
.quotes => for (comp.iquote_include_dirs.items) |dir| {
|
||||||
|
if (try find.checkIncludeDir(dir, .user)) |res| return res;
|
||||||
|
},
|
||||||
|
.angle_brackets => {},
|
||||||
|
}
|
||||||
for (comp.include_dirs.items) |dir| {
|
for (comp.include_dirs.items) |dir| {
|
||||||
if (try find.checkIncludeDir(dir, .user)) |res| return res;
|
if (try find.checkIncludeDir(dir, .user)) |res| return res;
|
||||||
}
|
}
|
||||||
@ -1876,7 +1909,7 @@ pub fn findInclude(
|
|||||||
/// include vs include_next
|
/// include vs include_next
|
||||||
which: WhichInclude,
|
which: WhichInclude,
|
||||||
) Compilation.Error!?Source {
|
) Compilation.Error!?Source {
|
||||||
const found = try FindInclude.run(comp, filename, switch (which) {
|
const found = try FindInclude.run(comp, filename, include_type, switch (which) {
|
||||||
.next => .{ .only_search_after_dir = comp.getSource(includer_token.source).path },
|
.next => .{ .only_search_after_dir = comp.getSource(includer_token.source).path },
|
||||||
.first => switch (include_type) {
|
.first => switch (include_type) {
|
||||||
.quotes => .{ .allow_same_dir = comp.getSource(includer_token.source).path },
|
.quotes => .{ .allow_same_dir = comp.getSource(includer_token.source).path },
|
||||||
|
|||||||
27
lib/compiler/aro/aro/Diagnostics.zig
vendored
27
lib/compiler/aro/aro/Diagnostics.zig
vendored
@ -194,6 +194,7 @@ pub const Option = enum {
|
|||||||
@"microsoft-anon-tag",
|
@"microsoft-anon-tag",
|
||||||
@"out-of-scope-function",
|
@"out-of-scope-function",
|
||||||
@"date-time",
|
@"date-time",
|
||||||
|
@"variadic-macro-arguments-omitted",
|
||||||
@"attribute-todo",
|
@"attribute-todo",
|
||||||
|
|
||||||
/// GNU extensions
|
/// GNU extensions
|
||||||
@ -496,27 +497,35 @@ pub fn formatArgs(w: *std.Io.Writer, fmt: []const u8, args: anytype) std.Io.Writ
|
|||||||
else => switch (@typeInfo(@TypeOf(arg))) {
|
else => switch (@typeInfo(@TypeOf(arg))) {
|
||||||
.int, .comptime_int => try Diagnostics.formatInt(w, fmt[i..], arg),
|
.int, .comptime_int => try Diagnostics.formatInt(w, fmt[i..], arg),
|
||||||
.pointer => try Diagnostics.formatString(w, fmt[i..], arg),
|
.pointer => try Diagnostics.formatString(w, fmt[i..], arg),
|
||||||
else => unreachable,
|
else => comptime unreachable,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
try w.writeAll(fmt[i..]);
|
try w.writeAll(fmt[i..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn formatString(w: *std.Io.Writer, fmt: []const u8, str: []const u8) std.Io.Writer.Error!usize {
|
pub fn templateIndex(w: *std.Io.Writer, fmt: []const u8, template: []const u8) std.Io.Writer.Error!usize {
|
||||||
const template = "{s}";
|
const i = std.mem.indexOf(u8, fmt, template) orelse {
|
||||||
const i = std.mem.indexOf(u8, fmt, template).?;
|
if (@import("builtin").mode == .Debug) {
|
||||||
|
std.debug.panic("template `{s}` not found in format string `{s}`", .{ template, fmt });
|
||||||
|
}
|
||||||
|
try w.print("template `{s}` not found in format string `{s}` (this is a bug in arocc)", .{ template, fmt });
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
try w.writeAll(fmt[0..i]);
|
try w.writeAll(fmt[0..i]);
|
||||||
try w.writeAll(str);
|
|
||||||
return i + template.len;
|
return i + template.len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn formatString(w: *std.Io.Writer, fmt: []const u8, str: []const u8) std.Io.Writer.Error!usize {
|
||||||
|
const i = templateIndex(w, fmt, "{s}");
|
||||||
|
try w.writeAll(str);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn formatInt(w: *std.Io.Writer, fmt: []const u8, int: anytype) std.Io.Writer.Error!usize {
|
pub fn formatInt(w: *std.Io.Writer, fmt: []const u8, int: anytype) std.Io.Writer.Error!usize {
|
||||||
const template = "{d}";
|
const i = templateIndex(w, fmt, "{d}");
|
||||||
const i = std.mem.indexOf(u8, fmt, template).?;
|
|
||||||
try w.writeAll(fmt[0..i]);
|
|
||||||
try w.printInt(int, 10, .lower, .{});
|
try w.printInt(int, 10, .lower, .{});
|
||||||
return i + template.len;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn addMessage(d: *Diagnostics, msg: Message) Compilation.Error!void {
|
fn addMessage(d: *Diagnostics, msg: Message) Compilation.Error!void {
|
||||||
|
|||||||
26
lib/compiler/aro/aro/Driver.zig
vendored
26
lib/compiler/aro/aro/Driver.zig
vendored
@ -203,6 +203,7 @@ pub const usage =
|
|||||||
\\ -fuse-line-directives Use `#line <num>` linemarkers in preprocessed output
|
\\ -fuse-line-directives Use `#line <num>` linemarkers in preprocessed output
|
||||||
\\ -fno-use-line-directives
|
\\ -fno-use-line-directives
|
||||||
\\ Use `# <num>` linemarkers in preprocessed output
|
\\ Use `# <num>` linemarkers in preprocessed output
|
||||||
|
\\ -iquote <dir> Add directory to QUOTE include search path
|
||||||
\\ -I <dir> Add directory to include search path
|
\\ -I <dir> Add directory to include search path
|
||||||
\\ -idirafter <dir> Add directory to AFTER include search path
|
\\ -idirafter <dir> Add directory to AFTER include search path
|
||||||
\\ -isystem <dir> Add directory to SYSTEM include search path
|
\\ -isystem <dir> Add directory to SYSTEM include search path
|
||||||
@ -275,7 +276,7 @@ pub fn parseArgs(
|
|||||||
var i: usize = 1;
|
var i: usize = 1;
|
||||||
var comment_arg: []const u8 = "";
|
var comment_arg: []const u8 = "";
|
||||||
var hosted: ?bool = null;
|
var hosted: ?bool = null;
|
||||||
var gnuc_version: []const u8 = "4.2.1"; // default value set by clang
|
var gnuc_version: ?[]const u8 = null;
|
||||||
var pic_arg: []const u8 = "";
|
var pic_arg: []const u8 = "";
|
||||||
var declspec_attrs: ?bool = null;
|
var declspec_attrs: ?bool = null;
|
||||||
var ms_extensions: ?bool = null;
|
var ms_extensions: ?bool = null;
|
||||||
@ -529,6 +530,17 @@ pub fn parseArgs(
|
|||||||
path = args[i];
|
path = args[i];
|
||||||
}
|
}
|
||||||
try d.comp.system_include_dirs.append(d.comp.gpa, path);
|
try d.comp.system_include_dirs.append(d.comp.gpa, path);
|
||||||
|
} else if (mem.startsWith(u8, arg, "-iquote")) {
|
||||||
|
var path = arg["-iquote".len..];
|
||||||
|
if (path.len == 0) {
|
||||||
|
i += 1;
|
||||||
|
if (i >= args.len) {
|
||||||
|
try d.err("expected argument after -iquote", .{});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
path = args[i];
|
||||||
|
}
|
||||||
|
try d.comp.iquote_include_dirs.append(d.comp.gpa, path);
|
||||||
} else if (mem.startsWith(u8, arg, "-F")) {
|
} else if (mem.startsWith(u8, arg, "-F")) {
|
||||||
var path = arg["-F".len..];
|
var path = arg["-F".len..];
|
||||||
if (path.len == 0) {
|
if (path.len == 0) {
|
||||||
@ -784,11 +796,13 @@ pub fn parseArgs(
|
|||||||
d.comp.target.os.tag = .freestanding;
|
d.comp.target.os.tag = .freestanding;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const version = GCCVersion.parse(gnuc_version);
|
if (gnuc_version) |unwrapped| {
|
||||||
if (version.major == -1) {
|
const version = GCCVersion.parse(unwrapped);
|
||||||
return d.fatal("invalid value '{0s}' in '-fgnuc-version={0s}'", .{gnuc_version});
|
if (version.major == -1) {
|
||||||
|
return d.fatal("invalid value '{s}' in '-fgnuc-version={s}'", .{ unwrapped, unwrapped });
|
||||||
|
}
|
||||||
|
d.comp.langopts.gnuc_version = version.toUnsigned();
|
||||||
}
|
}
|
||||||
d.comp.langopts.gnuc_version = version.toUnsigned();
|
|
||||||
const pic_level, const is_pie = try d.getPICMode(pic_arg);
|
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.pic_level = pic_level;
|
||||||
d.comp.code_gen_options.is_pie = is_pie;
|
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
|
|||||||
|
|
||||||
const fmt_template = "/tmp/{s}{s}";
|
const fmt_template = "/tmp/{s}{s}";
|
||||||
const fmt_args = .{
|
const fmt_args = .{
|
||||||
random_name,
|
@as([]const u8, &random_name),
|
||||||
extension,
|
extension,
|
||||||
};
|
};
|
||||||
return std.fmt.bufPrint(buf, fmt_template, fmt_args) catch return d.fatal("Filename too long for filesystem: " ++ fmt_template, fmt_args);
|
return std.fmt.bufPrint(buf, fmt_template, fmt_args) catch return d.fatal("Filename too long for filesystem: " ++ fmt_template, fmt_args);
|
||||||
|
|||||||
2
lib/compiler/aro/aro/Driver/GCCVersion.zig
vendored
2
lib/compiler/aro/aro/Driver/GCCVersion.zig
vendored
@ -57,7 +57,7 @@ pub fn parse(text: []const u8) GCCVersion {
|
|||||||
var good = bad;
|
var good = bad;
|
||||||
|
|
||||||
var it = mem.splitScalar(u8, text, '.');
|
var it = mem.splitScalar(u8, text, '.');
|
||||||
const first = it.next().?;
|
const first = it.first();
|
||||||
const second = it.next() orelse "";
|
const second = it.next() orelse "";
|
||||||
const rest = it.next() orelse "";
|
const rest = it.next() orelse "";
|
||||||
|
|
||||||
|
|||||||
10
lib/compiler/aro/aro/LangOpts.zig
vendored
10
lib/compiler/aro/aro/LangOpts.zig
vendored
@ -7,6 +7,14 @@ pub const Compiler = enum {
|
|||||||
clang,
|
clang,
|
||||||
gcc,
|
gcc,
|
||||||
msvc,
|
msvc,
|
||||||
|
|
||||||
|
pub fn defaultGccVersion(self: Compiler) u32 {
|
||||||
|
return switch (self) {
|
||||||
|
.clang => 4 * 10_000 + 2 * 100 + 1,
|
||||||
|
.gcc => 7 * 10_000 + 1 * 100 + 0,
|
||||||
|
.msvc => 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The floating-point evaluation method for intermediate results within a single expression
|
/// The floating-point evaluation method for intermediate results within a single expression
|
||||||
@ -139,7 +147,7 @@ preserve_comments_in_macros: bool = false,
|
|||||||
/// Used ONLY for generating __GNUC__ and related macros. Does not control the presence/absence of any features
|
/// Used ONLY for generating __GNUC__ and related macros. Does not control the presence/absence of any features
|
||||||
/// Encoded as major * 10,000 + minor * 100 + patch
|
/// Encoded as major * 10,000 + minor * 100 + patch
|
||||||
/// e.g. 4.2.1 == 40201
|
/// e.g. 4.2.1 == 40201
|
||||||
gnuc_version: u32 = 0,
|
gnuc_version: ?u32 = null,
|
||||||
|
|
||||||
pub fn setStandard(self: *LangOpts, name: []const u8) error{InvalidStandard}!void {
|
pub fn setStandard(self: *LangOpts, name: []const u8) error{InvalidStandard}!void {
|
||||||
self.standard = Standard.NameMap.get(name) orelse return error.InvalidStandard;
|
self.standard = Standard.NameMap.get(name) orelse return error.InvalidStandard;
|
||||||
|
|||||||
76
lib/compiler/aro/aro/Parser.zig
vendored
76
lib/compiler/aro/aro/Parser.zig
vendored
@ -469,7 +469,7 @@ fn formatArgs(p: *Parser, w: *std.Io.Writer, fmt: []const u8, args: anytype) !vo
|
|||||||
else => switch (@typeInfo(@TypeOf(arg))) {
|
else => switch (@typeInfo(@TypeOf(arg))) {
|
||||||
.int, .comptime_int => try Diagnostics.formatInt(w, fmt[i..], arg),
|
.int, .comptime_int => try Diagnostics.formatInt(w, fmt[i..], arg),
|
||||||
.pointer => try Diagnostics.formatString(w, fmt[i..], arg),
|
.pointer => try Diagnostics.formatString(w, fmt[i..], arg),
|
||||||
else => unreachable,
|
else => comptime unreachable,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -477,22 +477,18 @@ fn formatArgs(p: *Parser, w: *std.Io.Writer, fmt: []const u8, args: anytype) !vo
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn formatTokenId(w: *std.Io.Writer, fmt: []const u8, tok_id: Tree.Token.Id) !usize {
|
fn formatTokenId(w: *std.Io.Writer, fmt: []const u8, tok_id: Tree.Token.Id) !usize {
|
||||||
const template = "{tok_id}";
|
const i = Diagnostics.templateIndex(w, fmt, "{tok_id}");
|
||||||
const i = std.mem.indexOf(u8, fmt, template).?;
|
|
||||||
try w.writeAll(fmt[0..i]);
|
|
||||||
try w.writeAll(tok_id.symbol());
|
try w.writeAll(tok_id.symbol());
|
||||||
return i + template.len;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn formatQualType(p: *Parser, w: *std.Io.Writer, fmt: []const u8, qt: QualType) !usize {
|
fn formatQualType(p: *Parser, w: *std.Io.Writer, fmt: []const u8, qt: QualType) !usize {
|
||||||
const template = "{qt}";
|
const i = Diagnostics.templateIndex(w, fmt, "{qt}");
|
||||||
const i = std.mem.indexOf(u8, fmt, template).?;
|
|
||||||
try w.writeAll(fmt[0..i]);
|
|
||||||
try w.writeByte('\'');
|
try w.writeByte('\'');
|
||||||
try qt.print(p.comp, w);
|
try qt.print(p.comp, w);
|
||||||
try w.writeByte('\'');
|
try w.writeByte('\'');
|
||||||
|
|
||||||
if (qt.isC23Auto()) return i + template.len;
|
if (qt.isC23Auto()) return i;
|
||||||
if (qt.get(p.comp, .vector)) |vector_ty| {
|
if (qt.get(p.comp, .vector)) |vector_ty| {
|
||||||
try w.print(" (vector of {d} '", .{vector_ty.len});
|
try w.print(" (vector of {d} '", .{vector_ty.len});
|
||||||
try vector_ty.elem.printDesugared(p.comp, w);
|
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)
|
|||||||
try qt.printDesugared(p.comp, w);
|
try qt.printDesugared(p.comp, w);
|
||||||
try w.writeAll("')");
|
try w.writeAll("')");
|
||||||
}
|
}
|
||||||
return i + template.len;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn formatResult(p: *Parser, w: *std.Io.Writer, fmt: []const u8, res: Result) !usize {
|
fn formatResult(p: *Parser, w: *std.Io.Writer, fmt: []const u8, res: Result) !usize {
|
||||||
const template = "{value}";
|
const i = Diagnostics.templateIndex(w, fmt, "{value}");
|
||||||
const i = std.mem.indexOf(u8, fmt, template).?;
|
|
||||||
try w.writeAll(fmt[0..i]);
|
|
||||||
|
|
||||||
switch (res.val.opt_ref) {
|
switch (res.val.opt_ref) {
|
||||||
.none => try w.writeAll("(none)"),
|
.none => try w.writeAll("(none)"),
|
||||||
.null => try w.writeAll("nullptr_t"),
|
.null => try w.writeAll("nullptr_t"),
|
||||||
@ -521,8 +514,7 @@ fn formatResult(p: *Parser, w: *std.Io.Writer, fmt: []const u8, res: Result) !us
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
return i;
|
||||||
return i + template.len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Normalized = struct {
|
const Normalized = struct {
|
||||||
@ -532,10 +524,8 @@ const Normalized = struct {
|
|||||||
return .{ .str = str };
|
return .{ .str = str };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn format(ctx: Normalized, w: *std.Io.Writer, fmt_str: []const u8) !usize {
|
pub fn format(ctx: Normalized, w: *std.Io.Writer, fmt: []const u8) !usize {
|
||||||
const template = "{normalized}";
|
const i = Diagnostics.templateIndex(w, fmt, "{normalized}");
|
||||||
const i = std.mem.indexOf(u8, fmt_str, template).?;
|
|
||||||
try w.writeAll(fmt_str[0..i]);
|
|
||||||
var it: std.unicode.Utf8Iterator = .{
|
var it: std.unicode.Utf8Iterator = .{
|
||||||
.bytes = ctx.str,
|
.bytes = ctx.str,
|
||||||
.i = 0,
|
.i = 0,
|
||||||
@ -557,7 +547,7 @@ const Normalized = struct {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return i + template.len;
|
return i;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -568,12 +558,10 @@ const Codepoint = struct {
|
|||||||
return .{ .codepoint = codepoint };
|
return .{ .codepoint = codepoint };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn format(ctx: Codepoint, w: *std.Io.Writer, fmt_str: []const u8) !usize {
|
pub fn format(ctx: Codepoint, w: *std.Io.Writer, fmt: []const u8) !usize {
|
||||||
const template = "{codepoint}";
|
const i = Diagnostics.templateIndex(w, fmt, "{codepoint}");
|
||||||
const i = std.mem.indexOf(u8, fmt_str, template).?;
|
|
||||||
try w.writeAll(fmt_str[0..i]);
|
|
||||||
try w.print("{X:0>4}", .{ctx.codepoint});
|
try w.print("{X:0>4}", .{ctx.codepoint});
|
||||||
return i + template.len;
|
return i;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -584,12 +572,10 @@ const Escaped = struct {
|
|||||||
return .{ .str = str };
|
return .{ .str = str };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn format(ctx: Escaped, w: *std.Io.Writer, fmt_str: []const u8) !usize {
|
pub fn format(ctx: Escaped, w: *std.Io.Writer, fmt: []const u8) !usize {
|
||||||
const template = "{s}";
|
const i = Diagnostics.templateIndex(w, fmt, "{s}");
|
||||||
const i = std.mem.indexOf(u8, fmt_str, template).?;
|
|
||||||
try w.writeAll(fmt_str[0..i]);
|
|
||||||
try std.zig.stringEscape(ctx.str, w);
|
try std.zig.stringEscape(ctx.str, w);
|
||||||
return i + template.len;
|
return i;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -626,11 +612,11 @@ pub fn errValueChanged(p: *Parser, tok_i: TokenIndex, diagnostic: Diagnostic, re
|
|||||||
fn checkDeprecatedUnavailable(p: *Parser, ty: QualType, usage_tok: TokenIndex, decl_tok: TokenIndex) !void {
|
fn checkDeprecatedUnavailable(p: *Parser, ty: QualType, usage_tok: TokenIndex, decl_tok: TokenIndex) !void {
|
||||||
if (ty.getAttribute(p.comp, .@"error")) |@"error"| {
|
if (ty.getAttribute(p.comp, .@"error")) |@"error"| {
|
||||||
const msg_str = p.comp.interner.get(@"error".msg.ref()).bytes;
|
const msg_str = p.comp.interner.get(@"error".msg.ref()).bytes;
|
||||||
try p.err(usage_tok, .error_attribute, .{ p.tokSlice(@"error".__name_tok), std.zig.fmtString(msg_str) });
|
try p.err(usage_tok, .error_attribute, .{ p.tokSlice(@"error".__name_tok), Escaped.init(msg_str) });
|
||||||
}
|
}
|
||||||
if (ty.getAttribute(p.comp, .warning)) |warning| {
|
if (ty.getAttribute(p.comp, .warning)) |warning| {
|
||||||
const msg_str = p.comp.interner.get(warning.msg.ref()).bytes;
|
const msg_str = p.comp.interner.get(warning.msg.ref()).bytes;
|
||||||
try p.err(usage_tok, .warning_attribute, .{ p.tokSlice(warning.__name_tok), std.zig.fmtString(msg_str) });
|
try p.err(usage_tok, .warning_attribute, .{ p.tokSlice(warning.__name_tok), Escaped.init(msg_str) });
|
||||||
}
|
}
|
||||||
if (ty.getAttribute(p.comp, .unavailable)) |unavailable| {
|
if (ty.getAttribute(p.comp, .unavailable)) |unavailable| {
|
||||||
try p.errDeprecated(usage_tok, .unavailable, unavailable.msg);
|
try p.errDeprecated(usage_tok, .unavailable, unavailable.msg);
|
||||||
@ -4734,7 +4720,7 @@ fn asmOperand(p: *Parser, names: *std.ArrayList(?TokenIndex), constraints: *Node
|
|||||||
try constraints.append(gpa, constraint.node);
|
try constraints.append(gpa, constraint.node);
|
||||||
|
|
||||||
const l_paren = p.eatToken(.l_paren) orelse {
|
const l_paren = p.eatToken(.l_paren) orelse {
|
||||||
try p.err(p.tok_i, .expected_token, .{ p.tok_ids[p.tok_i], .l_paren });
|
try p.err(p.tok_i, .expected_token, .{ p.tok_ids[p.tok_i], Token.Id.l_paren });
|
||||||
return error.ParsingFailed;
|
return error.ParsingFailed;
|
||||||
};
|
};
|
||||||
const maybe_res = try p.expr();
|
const maybe_res = try p.expr();
|
||||||
@ -10221,12 +10207,30 @@ test "Node locations" {
|
|||||||
try std.testing.expectEqual(0, comp.diagnostics.total);
|
try std.testing.expectEqual(0, comp.diagnostics.total);
|
||||||
for (tree.root_decls.items[tree.root_decls.items.len - 3 ..], 0..) |node, i| {
|
for (tree.root_decls.items[tree.root_decls.items.len - 3 ..], 0..) |node, i| {
|
||||||
const slice = tree.tokSlice(node.tok(&tree));
|
const slice = tree.tokSlice(node.tok(&tree));
|
||||||
const expected = switch (i) {
|
const expected_slice = switch (i) {
|
||||||
0 => "foo",
|
0 => "foo",
|
||||||
1 => "bar",
|
1 => "bar",
|
||||||
2 => "main",
|
2 => "main",
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
try std.testing.expectEqualStrings(expected, slice);
|
try std.testing.expectEqualStrings(expected_slice, slice);
|
||||||
|
|
||||||
|
const loc = node.loc(&tree).expand(&comp);
|
||||||
|
const expected_col: u32 = switch (i) {
|
||||||
|
0 => 5,
|
||||||
|
1 => 5,
|
||||||
|
2 => 5,
|
||||||
|
else => unreachable,
|
||||||
|
};
|
||||||
|
try std.testing.expectEqual(expected_col, loc.col);
|
||||||
|
|
||||||
|
const expected_line_no = i + 1;
|
||||||
|
try std.testing.expectEqual(expected_line_no, loc.line_no);
|
||||||
|
|
||||||
|
const expected_source_path = "file.c";
|
||||||
|
try std.testing.expectEqualStrings(expected_source_path, loc.path);
|
||||||
|
|
||||||
|
const expected_source_kind = Source.Kind.user;
|
||||||
|
try std.testing.expectEqual(expected_source_kind, loc.kind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
5
lib/compiler/aro/aro/Preprocessor.zig
vendored
5
lib/compiler/aro/aro/Preprocessor.zig
vendored
@ -1703,7 +1703,10 @@ fn expandFuncMacro(
|
|||||||
else
|
else
|
||||||
&[1]TokenWithExpansionLocs{tokFromRaw(raw_next)},
|
&[1]TokenWithExpansionLocs{tokFromRaw(raw_next)},
|
||||||
.macro_param, .macro_param_no_expand => getPasteArgs(args.items[raw_next.end]),
|
.macro_param, .macro_param_no_expand => getPasteArgs(args.items[raw_next.end]),
|
||||||
.keyword_va_args => variable_arguments.items,
|
.keyword_va_args => if (variable_arguments.items.len == 0) blk: {
|
||||||
|
try pp.err(raw_next, .no_argument_variadic_macro, .{});
|
||||||
|
break :blk &[1]TokenWithExpansionLocs{.{ .id = .placemarker, .loc = .{ .id = .generated } }};
|
||||||
|
} else variable_arguments.items,
|
||||||
.keyword_va_opt => blk: {
|
.keyword_va_opt => blk: {
|
||||||
try pp.expandVaOpt(&va_opt_buf, raw_next, variable_arguments.items.len != 0);
|
try pp.expandVaOpt(&va_opt_buf, raw_next, variable_arguments.items.len != 0);
|
||||||
if (va_opt_buf.items.len == 0) break;
|
if (va_opt_buf.items.len == 0) break;
|
||||||
|
|||||||
@ -449,3 +449,10 @@ pub const date_time: Diagnostic = .{
|
|||||||
.opt = .@"date-time",
|
.opt = .@"date-time",
|
||||||
.show_in_system_headers = true,
|
.show_in_system_headers = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const no_argument_variadic_macro: Diagnostic = .{
|
||||||
|
.fmt = "passing no argument for the '...' parameter of a variadic macro is incompatible with C standards before C23",
|
||||||
|
.opt = .@"variadic-macro-arguments-omitted",
|
||||||
|
.kind = .off,
|
||||||
|
.extension = true,
|
||||||
|
};
|
||||||
|
|||||||
4
lib/compiler/aro/aro/Tree.zig
vendored
4
lib/compiler/aro/aro/Tree.zig
vendored
@ -1699,9 +1699,9 @@ pub const Node = union(enum) {
|
|||||||
return tree.nodes.items(.tok)[@intFromEnum(index)];
|
return tree.nodes.items(.tok)[@intFromEnum(index)];
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn loc(index: Index, tree: *const Tree) ?Source.Location {
|
pub fn loc(index: Index, tree: *const Tree) Source.Location {
|
||||||
const tok_i = index.tok(tree);
|
const tok_i = index.tok(tree);
|
||||||
return tree.tokens.items(.loc)[@intFromEnum(tok_i)];
|
return tree.tokens.items(.loc)[tok_i];
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn qt(index: Index, tree: *const Tree) QualType {
|
pub fn qt(index: Index, tree: *const Tree) QualType {
|
||||||
|
|||||||
4
lib/compiler/aro/aro/target.zig
vendored
4
lib/compiler/aro/aro/target.zig
vendored
@ -681,10 +681,12 @@ pub fn toLLVMTriple(target: std.Target, buf: []u8) []const u8 {
|
|||||||
.driverkit => "driverkit",
|
.driverkit => "driverkit",
|
||||||
.visionos => "xros",
|
.visionos => "xros",
|
||||||
.serenity => "serenity",
|
.serenity => "serenity",
|
||||||
|
.vulkan => "vulkan",
|
||||||
.managarm => "managarm",
|
.managarm => "managarm",
|
||||||
|
.@"3ds",
|
||||||
|
.vita,
|
||||||
.opencl,
|
.opencl,
|
||||||
.opengl,
|
.opengl,
|
||||||
.vulkan,
|
|
||||||
.plan9,
|
.plan9,
|
||||||
.other,
|
.other,
|
||||||
=> "unknown",
|
=> "unknown",
|
||||||
|
|||||||
11
lib/compiler/aro/aro/text_literal.zig
vendored
11
lib/compiler/aro/aro/text_literal.zig
vendored
@ -154,17 +154,14 @@ pub const Ascii = struct {
|
|||||||
return .{ .val = @intCast(val) };
|
return .{ .val = @intCast(val) };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn format(ctx: Ascii, w: *std.Io.Writer, fmt_str: []const u8) !usize {
|
pub fn format(ctx: Ascii, w: *std.Io.Writer, fmt: []const u8) !usize {
|
||||||
const template = "{c}";
|
const i = Diagnostics.templateIndex(w, fmt, "{c}");
|
||||||
const i = std.mem.indexOf(u8, fmt_str, template).?;
|
|
||||||
try w.writeAll(fmt_str[0..i]);
|
|
||||||
|
|
||||||
if (std.ascii.isPrint(ctx.val)) {
|
if (std.ascii.isPrint(ctx.val)) {
|
||||||
try w.writeByte(ctx.val);
|
try w.writeByte(ctx.val);
|
||||||
} else {
|
} else {
|
||||||
try w.print("x{x:0>2}", .{ctx.val});
|
try w.print("x{x:0>2}", .{ctx.val});
|
||||||
}
|
}
|
||||||
return i + template.len;
|
return i;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -345,7 +342,7 @@ pub const Parser = struct {
|
|||||||
else => switch (@typeInfo(@TypeOf(arg))) {
|
else => switch (@typeInfo(@TypeOf(arg))) {
|
||||||
.int, .comptime_int => try Diagnostics.formatInt(w, fmt[i..], arg),
|
.int, .comptime_int => try Diagnostics.formatInt(w, fmt[i..], arg),
|
||||||
.pointer => try Diagnostics.formatString(w, fmt[i..], arg),
|
.pointer => try Diagnostics.formatString(w, fmt[i..], arg),
|
||||||
else => unreachable,
|
else => comptime unreachable,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -175,8 +175,10 @@ pub fn transMacro(mt: *MacroTranslator) ParseError!void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn createMacroFn(mt: *MacroTranslator, name: []const u8, ref: ZigNode, proto_alias: *ast.Payload.Func) !ZigNode {
|
fn createMacroFn(mt: *MacroTranslator, name: []const u8, ref: ZigNode, proto_alias: *ast.Payload.Func) !ZigNode {
|
||||||
var fn_params = std.array_list.Managed(ast.Payload.Param).init(mt.t.gpa);
|
const gpa = mt.t.gpa;
|
||||||
defer fn_params.deinit();
|
const arena = mt.t.arena;
|
||||||
|
var fn_params: std.ArrayList(ast.Payload.Param) = .empty;
|
||||||
|
defer fn_params.deinit(gpa);
|
||||||
|
|
||||||
var block_scope = try Scope.Block.init(mt.t, &mt.t.global_scope.base, false);
|
var block_scope = try Scope.Block.init(mt.t, &mt.t.global_scope.base, false);
|
||||||
defer block_scope.deinit();
|
defer block_scope.deinit();
|
||||||
@ -184,7 +186,7 @@ fn createMacroFn(mt: *MacroTranslator, name: []const u8, ref: ZigNode, proto_ali
|
|||||||
for (proto_alias.data.params) |param| {
|
for (proto_alias.data.params) |param| {
|
||||||
const param_name = try block_scope.makeMangledName(param.name orelse "arg");
|
const param_name = try block_scope.makeMangledName(param.name orelse "arg");
|
||||||
|
|
||||||
try fn_params.append(.{
|
try fn_params.append(gpa, .{
|
||||||
.name = param_name,
|
.name = param_name,
|
||||||
.type = param.type,
|
.type = param.type,
|
||||||
.is_noalias = param.is_noalias,
|
.is_noalias = param.is_noalias,
|
||||||
@ -198,27 +200,28 @@ fn createMacroFn(mt: *MacroTranslator, name: []const u8, ref: ZigNode, proto_ali
|
|||||||
else
|
else
|
||||||
unreachable;
|
unreachable;
|
||||||
|
|
||||||
const unwrap_expr = try ZigTag.unwrap.create(mt.t.arena, init);
|
const unwrap_expr = try ZigTag.unwrap.create(arena, init);
|
||||||
const args = try mt.t.arena.alloc(ZigNode, fn_params.items.len);
|
const args = try arena.alloc(ZigNode, fn_params.items.len);
|
||||||
for (fn_params.items, 0..) |param, i| {
|
for (fn_params.items, 0..) |param, i| {
|
||||||
args[i] = try ZigTag.identifier.create(mt.t.arena, param.name.?);
|
args[i] = try ZigTag.identifier.create(arena, param.name.?);
|
||||||
}
|
}
|
||||||
const call_expr = try ZigTag.call.create(mt.t.arena, .{
|
const call_expr = try ZigTag.call.create(arena, .{
|
||||||
.lhs = unwrap_expr,
|
.lhs = unwrap_expr,
|
||||||
.args = args,
|
.args = args,
|
||||||
});
|
});
|
||||||
const return_expr = try ZigTag.@"return".create(mt.t.arena, call_expr);
|
const return_expr = try ZigTag.@"return".create(arena, call_expr);
|
||||||
const block = try ZigTag.block_single.create(mt.t.arena, return_expr);
|
const block = try ZigTag.block_single.create(arena, return_expr);
|
||||||
|
|
||||||
return ZigTag.pub_inline_fn.create(mt.t.arena, .{
|
return ZigTag.pub_inline_fn.create(arena, .{
|
||||||
.name = name,
|
.name = name,
|
||||||
.params = try mt.t.arena.dupe(ast.Payload.Param, fn_params.items),
|
.params = try arena.dupe(ast.Payload.Param, fn_params.items),
|
||||||
.return_type = proto_alias.data.return_type,
|
.return_type = proto_alias.data.return_type,
|
||||||
.body = block,
|
.body = block,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseCExpr(mt: *MacroTranslator, scope: *Scope) ParseError!ZigNode {
|
fn parseCExpr(mt: *MacroTranslator, scope: *Scope) ParseError!ZigNode {
|
||||||
|
const arena = mt.t.arena;
|
||||||
// TODO parseCAssignExpr here
|
// TODO parseCAssignExpr here
|
||||||
var block_scope = try Scope.Block.init(mt.t, scope, true);
|
var block_scope = try Scope.Block.init(mt.t, scope, true);
|
||||||
defer block_scope.deinit();
|
defer block_scope.deinit();
|
||||||
@ -229,14 +232,14 @@ fn parseCExpr(mt: *MacroTranslator, scope: *Scope) ParseError!ZigNode {
|
|||||||
var last = node;
|
var last = node;
|
||||||
while (true) {
|
while (true) {
|
||||||
// suppress result
|
// suppress result
|
||||||
const ignore = try ZigTag.discard.create(mt.t.arena, .{ .should_skip = false, .value = last });
|
const ignore = try ZigTag.discard.create(arena, .{ .should_skip = false, .value = last });
|
||||||
try block_scope.statements.append(mt.t.gpa, ignore);
|
try block_scope.statements.append(mt.t.gpa, ignore);
|
||||||
|
|
||||||
last = try mt.parseCCondExpr(&block_scope.base);
|
last = try mt.parseCCondExpr(&block_scope.base);
|
||||||
if (!mt.eat(.comma)) break;
|
if (!mt.eat(.comma)) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const break_node = try ZigTag.break_val.create(mt.t.arena, .{
|
const break_node = try ZigTag.break_val.create(arena, .{
|
||||||
.label = block_scope.label,
|
.label = block_scope.label,
|
||||||
.val = last,
|
.val = last,
|
||||||
});
|
});
|
||||||
@ -245,10 +248,11 @@ fn parseCExpr(mt: *MacroTranslator, scope: *Scope) ParseError!ZigNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn parseCNumLit(mt: *MacroTranslator) ParseError!ZigNode {
|
fn parseCNumLit(mt: *MacroTranslator) ParseError!ZigNode {
|
||||||
|
const arena = mt.t.arena;
|
||||||
const lit_bytes = mt.tokSlice();
|
const lit_bytes = mt.tokSlice();
|
||||||
mt.i += 1;
|
mt.i += 1;
|
||||||
|
|
||||||
var bytes = try std.ArrayListUnmanaged(u8).initCapacity(mt.t.arena, lit_bytes.len + 3);
|
var bytes = try std.ArrayListUnmanaged(u8).initCapacity(arena, lit_bytes.len + 3);
|
||||||
|
|
||||||
const prefix = aro.Tree.Token.NumberPrefix.fromString(lit_bytes);
|
const prefix = aro.Tree.Token.NumberPrefix.fromString(lit_bytes);
|
||||||
switch (prefix) {
|
switch (prefix) {
|
||||||
@ -330,7 +334,7 @@ fn parseCNumLit(mt: *MacroTranslator) ParseError!ZigNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (is_float) {
|
if (is_float) {
|
||||||
const type_node = try ZigTag.type.create(mt.t.arena, switch (suffix) {
|
const type_node = try ZigTag.type.create(arena, switch (suffix) {
|
||||||
.F16 => "f16",
|
.F16 => "f16",
|
||||||
.F => "f32",
|
.F => "f32",
|
||||||
.None => "f64",
|
.None => "f64",
|
||||||
@ -339,10 +343,10 @@ fn parseCNumLit(mt: *MacroTranslator) ParseError!ZigNode {
|
|||||||
.Q, .F128 => "f128",
|
.Q, .F128 => "f128",
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
});
|
});
|
||||||
const rhs = try ZigTag.float_literal.create(mt.t.arena, bytes.items);
|
const rhs = try ZigTag.float_literal.create(arena, bytes.items);
|
||||||
return ZigTag.as.create(mt.t.arena, .{ .lhs = type_node, .rhs = rhs });
|
return ZigTag.as.create(arena, .{ .lhs = type_node, .rhs = rhs });
|
||||||
} else {
|
} else {
|
||||||
const type_node = try ZigTag.type.create(mt.t.arena, switch (suffix) {
|
const type_node = try ZigTag.type.create(arena, switch (suffix) {
|
||||||
.None => "c_int",
|
.None => "c_int",
|
||||||
.U => "c_uint",
|
.U => "c_uint",
|
||||||
.L => "c_long",
|
.L => "c_long",
|
||||||
@ -365,11 +369,11 @@ fn parseCNumLit(mt: *MacroTranslator) ParseError!ZigNode {
|
|||||||
else => unreachable,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
|
|
||||||
const literal_node = try ZigTag.integer_literal.create(mt.t.arena, bytes.items);
|
const literal_node = try ZigTag.integer_literal.create(arena, bytes.items);
|
||||||
if (guaranteed_to_fit) {
|
if (guaranteed_to_fit) {
|
||||||
return ZigTag.as.create(mt.t.arena, .{ .lhs = type_node, .rhs = literal_node });
|
return ZigTag.as.create(arena, .{ .lhs = type_node, .rhs = literal_node });
|
||||||
} else {
|
} else {
|
||||||
return mt.t.createHelperCallNode(.promoteIntLiteral, &.{ type_node, literal_node, try ZigTag.enum_literal.create(mt.t.arena, @tagName(prefix)) });
|
return mt.t.createHelperCallNode(.promoteIntLiteral, &.{ type_node, literal_node, try ZigTag.enum_literal.create(arena, @tagName(prefix)) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -563,6 +567,7 @@ fn escapeUnprintables(mt: *MacroTranslator) ![]const u8 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn parseCPrimaryExpr(mt: *MacroTranslator, scope: *Scope) ParseError!ZigNode {
|
fn parseCPrimaryExpr(mt: *MacroTranslator, scope: *Scope) ParseError!ZigNode {
|
||||||
|
const arena = mt.t.arena;
|
||||||
const tok = mt.peek();
|
const tok = mt.peek();
|
||||||
switch (tok) {
|
switch (tok) {
|
||||||
.char_literal,
|
.char_literal,
|
||||||
@ -573,12 +578,12 @@ fn parseCPrimaryExpr(mt: *MacroTranslator, scope: *Scope) ParseError!ZigNode {
|
|||||||
=> {
|
=> {
|
||||||
const slice = mt.tokSlice();
|
const slice = mt.tokSlice();
|
||||||
if (slice[0] != '\'' or slice[1] == '\\' or slice.len == 3) {
|
if (slice[0] != '\'' or slice[1] == '\\' or slice.len == 3) {
|
||||||
return ZigTag.char_literal.create(mt.t.arena, try mt.escapeUnprintables());
|
return ZigTag.char_literal.create(arena, try mt.escapeUnprintables());
|
||||||
} else {
|
} else {
|
||||||
mt.i += 1;
|
mt.i += 1;
|
||||||
|
|
||||||
const str = try std.fmt.allocPrint(mt.t.arena, "0x{x}", .{slice[1 .. slice.len - 1]});
|
const str = try std.fmt.allocPrint(arena, "0x{x}", .{slice[1 .. slice.len - 1]});
|
||||||
return ZigTag.integer_literal.create(mt.t.arena, str);
|
return ZigTag.integer_literal.create(arena, str);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.string_literal,
|
.string_literal,
|
||||||
@ -586,7 +591,7 @@ fn parseCPrimaryExpr(mt: *MacroTranslator, scope: *Scope) ParseError!ZigNode {
|
|||||||
.string_literal_utf_8,
|
.string_literal_utf_8,
|
||||||
.string_literal_utf_32,
|
.string_literal_utf_32,
|
||||||
.string_literal_wide,
|
.string_literal_wide,
|
||||||
=> return ZigTag.string_literal.create(mt.t.arena, try mt.escapeUnprintables()),
|
=> return ZigTag.string_literal.create(arena, try mt.escapeUnprintables()),
|
||||||
.pp_num => return mt.parseCNumLit(),
|
.pp_num => return mt.parseCNumLit(),
|
||||||
.l_paren => {
|
.l_paren => {
|
||||||
mt.i += 1;
|
mt.i += 1;
|
||||||
@ -600,7 +605,7 @@ fn parseCPrimaryExpr(mt: *MacroTranslator, scope: *Scope) ParseError!ZigNode {
|
|||||||
mt.i += 1;
|
mt.i += 1;
|
||||||
|
|
||||||
const mangled_name = scope.getAlias(param) orelse param;
|
const mangled_name = scope.getAlias(param) orelse param;
|
||||||
return try ZigTag.identifier.create(mt.t.arena, mangled_name);
|
return try ZigTag.identifier.create(arena, mangled_name);
|
||||||
},
|
},
|
||||||
.identifier, .extended_identifier => {
|
.identifier, .extended_identifier => {
|
||||||
const slice = mt.tokSlice();
|
const slice = mt.tokSlice();
|
||||||
@ -608,17 +613,17 @@ fn parseCPrimaryExpr(mt: *MacroTranslator, scope: *Scope) ParseError!ZigNode {
|
|||||||
|
|
||||||
const mangled_name = scope.getAlias(slice) orelse slice;
|
const mangled_name = scope.getAlias(slice) orelse slice;
|
||||||
if (Translator.builtin_typedef_map.get(mangled_name)) |ty| {
|
if (Translator.builtin_typedef_map.get(mangled_name)) |ty| {
|
||||||
return ZigTag.type.create(mt.t.arena, ty);
|
return ZigTag.type.create(arena, ty);
|
||||||
}
|
}
|
||||||
if (builtins.map.get(mangled_name)) |builtin| {
|
if (builtins.map.get(mangled_name)) |builtin| {
|
||||||
const builtin_identifier = try ZigTag.identifier.create(mt.t.arena, "__builtin");
|
const builtin_identifier = try ZigTag.identifier.create(arena, "__builtin");
|
||||||
return ZigTag.field_access.create(mt.t.arena, .{
|
return ZigTag.field_access.create(arena, .{
|
||||||
.lhs = builtin_identifier,
|
.lhs = builtin_identifier,
|
||||||
.field_name = builtin.name,
|
.field_name = builtin.name,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const identifier = try ZigTag.identifier.create(mt.t.arena, mangled_name);
|
const identifier = try ZigTag.identifier.create(arena, mangled_name);
|
||||||
scope.skipVariableDiscard(mangled_name);
|
scope.skipVariableDiscard(mangled_name);
|
||||||
refs_var: {
|
refs_var: {
|
||||||
const ident_node = mt.t.global_scope.sym_table.get(slice) orelse break :refs_var;
|
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
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn parseCPostfixExprInner(mt: *MacroTranslator, scope: *Scope, type_name: ?ZigNode) ParseError!ZigNode {
|
fn parseCPostfixExprInner(mt: *MacroTranslator, scope: *Scope, type_name: ?ZigNode) ParseError!ZigNode {
|
||||||
|
const gpa = mt.t.gpa;
|
||||||
|
const arena = mt.t.arena;
|
||||||
var node = type_name orelse try mt.parseCPrimaryExpr(scope);
|
var node = type_name orelse try mt.parseCPrimaryExpr(scope);
|
||||||
while (true) {
|
while (true) {
|
||||||
switch (mt.peek()) {
|
switch (mt.peek()) {
|
||||||
@ -1122,39 +1129,39 @@ fn parseCPostfixExprInner(mt: *MacroTranslator, scope: *Scope, type_name: ?ZigNo
|
|||||||
const field_name = mt.tokSlice();
|
const field_name = mt.tokSlice();
|
||||||
try mt.expect(.identifier);
|
try mt.expect(.identifier);
|
||||||
|
|
||||||
node = try ZigTag.field_access.create(mt.t.arena, .{ .lhs = node, .field_name = field_name });
|
node = try ZigTag.field_access.create(arena, .{ .lhs = node, .field_name = field_name });
|
||||||
},
|
},
|
||||||
.arrow => {
|
.arrow => {
|
||||||
mt.i += 1;
|
mt.i += 1;
|
||||||
const field_name = mt.tokSlice();
|
const field_name = mt.tokSlice();
|
||||||
try mt.expect(.identifier);
|
try mt.expect(.identifier);
|
||||||
|
|
||||||
const deref = try ZigTag.deref.create(mt.t.arena, node);
|
const deref = try ZigTag.deref.create(arena, node);
|
||||||
node = try ZigTag.field_access.create(mt.t.arena, .{ .lhs = deref, .field_name = field_name });
|
node = try ZigTag.field_access.create(arena, .{ .lhs = deref, .field_name = field_name });
|
||||||
},
|
},
|
||||||
.l_bracket => {
|
.l_bracket => {
|
||||||
mt.i += 1;
|
mt.i += 1;
|
||||||
|
|
||||||
const index_val = try mt.macroIntFromBool(try mt.parseCExpr(scope));
|
const index_val = try mt.macroIntFromBool(try mt.parseCExpr(scope));
|
||||||
const index = try ZigTag.as.create(mt.t.arena, .{
|
const index = try ZigTag.as.create(arena, .{
|
||||||
.lhs = try ZigTag.type.create(mt.t.arena, "usize"),
|
.lhs = try ZigTag.type.create(arena, "usize"),
|
||||||
.rhs = try ZigTag.int_cast.create(mt.t.arena, index_val),
|
.rhs = try ZigTag.int_cast.create(arena, index_val),
|
||||||
});
|
});
|
||||||
node = try ZigTag.array_access.create(mt.t.arena, .{ .lhs = node, .rhs = index });
|
node = try ZigTag.array_access.create(arena, .{ .lhs = node, .rhs = index });
|
||||||
try mt.expect(.r_bracket);
|
try mt.expect(.r_bracket);
|
||||||
},
|
},
|
||||||
.l_paren => {
|
.l_paren => {
|
||||||
mt.i += 1;
|
mt.i += 1;
|
||||||
|
|
||||||
if (mt.eat(.r_paren)) {
|
if (mt.eat(.r_paren)) {
|
||||||
node = try ZigTag.call.create(mt.t.arena, .{ .lhs = node, .args = &.{} });
|
node = try ZigTag.call.create(arena, .{ .lhs = node, .args = &.{} });
|
||||||
} else {
|
} else {
|
||||||
var args = std.array_list.Managed(ZigNode).init(mt.t.gpa);
|
var args: std.ArrayList(ZigNode) = .empty;
|
||||||
defer args.deinit();
|
defer args.deinit(gpa);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
const arg = try mt.parseCCondExpr(scope);
|
const arg = try mt.parseCCondExpr(scope);
|
||||||
try args.append(arg);
|
try args.append(gpa, arg);
|
||||||
|
|
||||||
const next_id = mt.peek();
|
const next_id = mt.peek();
|
||||||
switch (next_id) {
|
switch (next_id) {
|
||||||
@ -1171,7 +1178,7 @@ fn parseCPostfixExprInner(mt: *MacroTranslator, scope: *Scope, type_name: ?ZigNo
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
node = try ZigTag.call.create(mt.t.arena, .{ .lhs = node, .args = try mt.t.arena.dupe(ZigNode, args.items) });
|
node = try ZigTag.call.create(arena, .{ .lhs = node, .args = try arena.dupe(ZigNode, args.items) });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.l_brace => {
|
.l_brace => {
|
||||||
@ -1179,8 +1186,8 @@ fn parseCPostfixExprInner(mt: *MacroTranslator, scope: *Scope, type_name: ?ZigNo
|
|||||||
|
|
||||||
// Check for designated field initializers
|
// Check for designated field initializers
|
||||||
if (mt.peek() == .period) {
|
if (mt.peek() == .period) {
|
||||||
var init_vals = std.array_list.Managed(ast.Payload.ContainerInitDot.Initializer).init(mt.t.gpa);
|
var init_vals: std.ArrayList(ast.Payload.ContainerInitDot.Initializer) = .empty;
|
||||||
defer init_vals.deinit();
|
defer init_vals.deinit(gpa);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
try mt.expect(.period);
|
try mt.expect(.period);
|
||||||
@ -1189,7 +1196,7 @@ fn parseCPostfixExprInner(mt: *MacroTranslator, scope: *Scope, type_name: ?ZigNo
|
|||||||
try mt.expect(.equal);
|
try mt.expect(.equal);
|
||||||
|
|
||||||
const val = try mt.parseCCondExpr(scope);
|
const val = try mt.parseCCondExpr(scope);
|
||||||
try init_vals.append(.{ .name = name, .value = val });
|
try init_vals.append(gpa, .{ .name = name, .value = val });
|
||||||
|
|
||||||
const next_id = mt.peek();
|
const next_id = mt.peek();
|
||||||
switch (next_id) {
|
switch (next_id) {
|
||||||
@ -1206,17 +1213,17 @@ fn parseCPostfixExprInner(mt: *MacroTranslator, scope: *Scope, type_name: ?ZigNo
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const tuple_node = try ZigTag.container_init_dot.create(mt.t.arena, try mt.t.arena.dupe(ast.Payload.ContainerInitDot.Initializer, init_vals.items));
|
const tuple_node = try ZigTag.container_init_dot.create(arena, try arena.dupe(ast.Payload.ContainerInitDot.Initializer, init_vals.items));
|
||||||
node = try ZigTag.std_mem_zeroinit.create(mt.t.arena, .{ .lhs = node, .rhs = tuple_node });
|
node = try ZigTag.std_mem_zeroinit.create(arena, .{ .lhs = node, .rhs = tuple_node });
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var init_vals = std.array_list.Managed(ZigNode).init(mt.t.gpa);
|
var init_vals: std.ArrayList(ZigNode) = .empty;
|
||||||
defer init_vals.deinit();
|
defer init_vals.deinit(gpa);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
const val = try mt.parseCCondExpr(scope);
|
const val = try mt.parseCCondExpr(scope);
|
||||||
try init_vals.append(val);
|
try init_vals.append(gpa, val);
|
||||||
|
|
||||||
const next_id = mt.peek();
|
const next_id = mt.peek();
|
||||||
switch (next_id) {
|
switch (next_id) {
|
||||||
@ -1233,8 +1240,8 @@ fn parseCPostfixExprInner(mt: *MacroTranslator, scope: *Scope, type_name: ?ZigNo
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const tuple_node = try ZigTag.tuple.create(mt.t.arena, try mt.t.arena.dupe(ZigNode, init_vals.items));
|
const tuple_node = try ZigTag.tuple.create(arena, try arena.dupe(ZigNode, init_vals.items));
|
||||||
node = try ZigTag.std_mem_zeroinit.create(mt.t.arena, .{ .lhs = node, .rhs = tuple_node });
|
node = try ZigTag.std_mem_zeroinit.create(arena, .{ .lhs = node, .rhs = tuple_node });
|
||||||
},
|
},
|
||||||
.plus_plus, .minus_minus => {
|
.plus_plus, .minus_minus => {
|
||||||
try mt.fail("TODO postfix inc/dec expr", .{});
|
try mt.fail("TODO postfix inc/dec expr", .{});
|
||||||
|
|||||||
@ -91,11 +91,11 @@ const Pattern = struct {
|
|||||||
fn init(pl: *Pattern, allocator: mem.Allocator, template: Template) Error!void {
|
fn init(pl: *Pattern, allocator: mem.Allocator, template: Template) Error!void {
|
||||||
const source = template[0];
|
const source = template[0];
|
||||||
const impl = template[1];
|
const impl = template[1];
|
||||||
var tok_list = std.array_list.Managed(CToken).init(allocator);
|
var tok_list: std.ArrayList(CToken) = .empty;
|
||||||
defer tok_list.deinit();
|
defer tok_list.deinit(allocator);
|
||||||
|
|
||||||
pl.* = .{
|
pl.* = .{
|
||||||
.slicer = try tokenizeMacro(source, &tok_list),
|
.slicer = try tokenizeMacro(allocator, source, &tok_list),
|
||||||
.impl = impl,
|
.impl = impl,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -170,7 +170,7 @@ pub fn match(pl: PatternList, ms: MacroSlicer) Error!?Impl {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tokenizeMacro(source: []const u8, tok_list: *std.array_list.Managed(CToken)) Error!MacroSlicer {
|
fn tokenizeMacro(allocator: mem.Allocator, source: []const u8, tok_list: *std.ArrayList(CToken)) Error!MacroSlicer {
|
||||||
var param_count: u32 = 0;
|
var param_count: u32 = 0;
|
||||||
var param_buf: [8][]const u8 = undefined;
|
var param_buf: [8][]const u8 = undefined;
|
||||||
|
|
||||||
@ -207,7 +207,7 @@ fn tokenizeMacro(source: []const u8, tok_list: *std.array_list.Managed(CToken))
|
|||||||
const slice = source[tok.start..tok.end];
|
const slice = source[tok.start..tok.end];
|
||||||
for (param_buf[0..param_count], 0..) |param, i| {
|
for (param_buf[0..param_count], 0..) |param, i| {
|
||||||
if (std.mem.eql(u8, param, slice)) {
|
if (std.mem.eql(u8, param, slice)) {
|
||||||
try tok_list.append(.{
|
try tok_list.append(allocator, .{
|
||||||
.id = .macro_param,
|
.id = .macro_param,
|
||||||
.source = .unused,
|
.source = .unused,
|
||||||
.end = @intCast(i),
|
.end = @intCast(i),
|
||||||
@ -224,12 +224,12 @@ fn tokenizeMacro(source: []const u8, tok_list: *std.array_list.Managed(CToken))
|
|||||||
.nl, .eof => break,
|
.nl, .eof => break,
|
||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
try tok_list.append(tok);
|
try tok_list.append(allocator, tok);
|
||||||
}
|
}
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
.source = source,
|
.source = source,
|
||||||
.tokens = try tok_list.toOwnedSlice(),
|
.tokens = try tok_list.toOwnedSlice(allocator),
|
||||||
.params = param_count,
|
.params = param_count,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -243,9 +243,9 @@ test "Macro matching" {
|
|||||||
source: []const u8,
|
source: []const u8,
|
||||||
comptime expected_match: ?Impl,
|
comptime expected_match: ?Impl,
|
||||||
) !void {
|
) !void {
|
||||||
var tok_list = std.array_list.Managed(CToken).init(allocator);
|
var tok_list: std.ArrayList(CToken) = .empty;
|
||||||
defer tok_list.deinit();
|
defer tok_list.deinit(allocator);
|
||||||
const ms = try tokenizeMacro(source, &tok_list);
|
const ms = try tokenizeMacro(allocator, source, &tok_list);
|
||||||
defer allocator.free(ms.tokens);
|
defer allocator.free(ms.tokens);
|
||||||
|
|
||||||
const matched = try pattern_list.match(ms);
|
const matched = try pattern_list.match(ms);
|
||||||
|
|||||||
@ -216,10 +216,10 @@ pub fn translate(options: Options) mem.Allocator.Error![]u8 {
|
|||||||
|
|
||||||
try translator.global_scope.processContainerMemberFns();
|
try translator.global_scope.processContainerMemberFns();
|
||||||
|
|
||||||
var aw: std.Io.Writer.Allocating = .init(gpa);
|
var allocating: std.Io.Writer.Allocating = .init(gpa);
|
||||||
defer aw.deinit();
|
defer allocating.deinit();
|
||||||
|
|
||||||
aw.writer.writeAll(
|
allocating.writer.writeAll(
|
||||||
\\pub const __builtin = @import("std").zig.c_translation.builtins;
|
\\pub const __builtin = @import("std").zig.c_translation.builtins;
|
||||||
\\pub const __helpers = @import("std").zig.c_translation.helpers;
|
\\pub const __helpers = @import("std").zig.c_translation.helpers;
|
||||||
\\
|
\\
|
||||||
@ -231,8 +231,8 @@ pub fn translate(options: Options) mem.Allocator.Error![]u8 {
|
|||||||
gpa.free(zig_ast.source);
|
gpa.free(zig_ast.source);
|
||||||
zig_ast.deinit(gpa);
|
zig_ast.deinit(gpa);
|
||||||
}
|
}
|
||||||
zig_ast.render(gpa, &aw.writer, .{}) catch return error.OutOfMemory;
|
zig_ast.render(gpa, &allocating.writer, .{}) catch return error.OutOfMemory;
|
||||||
return aw.toOwnedSlice();
|
return allocating.toOwnedSlice();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepopulateGlobalNameTable(t: *Translator) !void {
|
fn prepopulateGlobalNameTable(t: *Translator) !void {
|
||||||
@ -489,11 +489,12 @@ fn transRecordDecl(t: *Translator, scope: *Scope, record_qt: QualType) Error!voi
|
|||||||
break :init ZigTag.opaque_literal.init();
|
break :init ZigTag.opaque_literal.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
var fields = try std.array_list.Managed(ast.Payload.Container.Field).initCapacity(t.gpa, record_ty.fields.len);
|
var fields: std.ArrayList(ast.Payload.Container.Field) = .empty;
|
||||||
defer fields.deinit();
|
defer fields.deinit(t.gpa);
|
||||||
|
try fields.ensureUnusedCapacity(t.gpa, record_ty.fields.len);
|
||||||
|
|
||||||
var functions = std.array_list.Managed(ZigNode).init(t.gpa);
|
var functions: std.ArrayList(ZigNode) = .empty;
|
||||||
defer functions.deinit();
|
defer functions.deinit(t.gpa);
|
||||||
|
|
||||||
var unnamed_field_count: u32 = 0;
|
var unnamed_field_count: u32 = 0;
|
||||||
|
|
||||||
@ -558,7 +559,7 @@ fn transRecordDecl(t: *Translator, scope: *Scope, record_qt: QualType) Error!voi
|
|||||||
field_name = try std.fmt.allocPrint(t.arena, "_{s}", .{field_name});
|
field_name = try std.fmt.allocPrint(t.arena, "_{s}", .{field_name});
|
||||||
|
|
||||||
const member = try t.createFlexibleMemberFn(member_name, field_name);
|
const member = try t.createFlexibleMemberFn(member_name, field_name);
|
||||||
try functions.append(member);
|
try functions.append(t.gpa, member);
|
||||||
|
|
||||||
break :field_type zero_array;
|
break :field_type zero_array;
|
||||||
}
|
}
|
||||||
@ -600,7 +601,7 @@ fn transRecordDecl(t: *Translator, scope: *Scope, record_qt: QualType) Error!voi
|
|||||||
const padding_bits = record_ty.layout.?.size_bits;
|
const padding_bits = record_ty.layout.?.size_bits;
|
||||||
const alignment_bits = record_ty.layout.?.field_alignment_bits;
|
const alignment_bits = record_ty.layout.?.field_alignment_bits;
|
||||||
|
|
||||||
try fields.append(.{
|
try fields.append(t.gpa, .{
|
||||||
.name = "_padding",
|
.name = "_padding",
|
||||||
.type = try ZigTag.type.create(t.arena, try std.fmt.allocPrint(t.arena, "u{d}", .{padding_bits})),
|
.type = try ZigTag.type.create(t.arena, try std.fmt.allocPrint(t.arena, "u{d}", .{padding_bits})),
|
||||||
.alignment = @divExact(alignment_bits, 8),
|
.alignment = @divExact(alignment_bits, 8),
|
||||||
@ -1789,8 +1790,8 @@ fn transSwitch(t: *Translator, scope: *Scope, switch_stmt: Node.SwitchStmt) Tran
|
|||||||
defer cond_scope.deinit();
|
defer cond_scope.deinit();
|
||||||
const switch_expr = try t.transExpr(&cond_scope.base, switch_stmt.cond, .used);
|
const switch_expr = try t.transExpr(&cond_scope.base, switch_stmt.cond, .used);
|
||||||
|
|
||||||
var cases = std.array_list.Managed(ZigNode).init(t.gpa);
|
var cases: std.ArrayList(ZigNode) = .empty;
|
||||||
defer cases.deinit();
|
defer cases.deinit(t.gpa);
|
||||||
var has_default = false;
|
var has_default = false;
|
||||||
|
|
||||||
const body_node = switch_stmt.body.get(t.tree);
|
const body_node = switch_stmt.body.get(t.tree);
|
||||||
@ -1803,21 +1804,21 @@ fn transSwitch(t: *Translator, scope: *Scope, switch_stmt: Node.SwitchStmt) Tran
|
|||||||
for (body, 0..) |stmt, i| {
|
for (body, 0..) |stmt, i| {
|
||||||
switch (stmt.get(t.tree)) {
|
switch (stmt.get(t.tree)) {
|
||||||
.case_stmt => {
|
.case_stmt => {
|
||||||
var items = std.array_list.Managed(ZigNode).init(t.gpa);
|
var items: std.ArrayList(ZigNode) = .empty;
|
||||||
defer items.deinit();
|
defer items.deinit(t.gpa);
|
||||||
const sub = try t.transCaseStmt(base_scope, stmt, &items);
|
const sub = try t.transCaseStmt(base_scope, stmt, &items);
|
||||||
const res = try t.transSwitchProngStmt(base_scope, sub, body[i..]);
|
const res = try t.transSwitchProngStmt(base_scope, sub, body[i..]);
|
||||||
|
|
||||||
if (items.items.len == 0) {
|
if (items.items.len == 0) {
|
||||||
has_default = true;
|
has_default = true;
|
||||||
const switch_else = try ZigTag.switch_else.create(t.arena, res);
|
const switch_else = try ZigTag.switch_else.create(t.arena, res);
|
||||||
try cases.append(switch_else);
|
try cases.append(t.gpa, switch_else);
|
||||||
} else {
|
} else {
|
||||||
const switch_prong = try ZigTag.switch_prong.create(t.arena, .{
|
const switch_prong = try ZigTag.switch_prong.create(t.arena, .{
|
||||||
.cases = try t.arena.dupe(ZigNode, items.items),
|
.cases = try t.arena.dupe(ZigNode, items.items),
|
||||||
.cond = res,
|
.cond = res,
|
||||||
});
|
});
|
||||||
try cases.append(switch_prong);
|
try cases.append(t.gpa, switch_prong);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.default_stmt => |default_stmt| {
|
.default_stmt => |default_stmt| {
|
||||||
@ -1833,7 +1834,7 @@ fn transSwitch(t: *Translator, scope: *Scope, switch_stmt: Node.SwitchStmt) Tran
|
|||||||
const res = try t.transSwitchProngStmt(base_scope, sub, body[i..]);
|
const res = try t.transSwitchProngStmt(base_scope, sub, body[i..]);
|
||||||
|
|
||||||
const switch_else = try ZigTag.switch_else.create(t.arena, res);
|
const switch_else = try ZigTag.switch_else.create(t.arena, res);
|
||||||
try cases.append(switch_else);
|
try cases.append(t.gpa, switch_else);
|
||||||
},
|
},
|
||||||
else => {}, // collected in transSwitchProngStmt
|
else => {}, // collected in transSwitchProngStmt
|
||||||
}
|
}
|
||||||
@ -1841,7 +1842,7 @@ fn transSwitch(t: *Translator, scope: *Scope, switch_stmt: Node.SwitchStmt) Tran
|
|||||||
|
|
||||||
if (!has_default) {
|
if (!has_default) {
|
||||||
const else_prong = try ZigTag.switch_else.create(t.arena, ZigTag.empty_block.init());
|
const else_prong = try ZigTag.switch_else.create(t.arena, ZigTag.empty_block.init());
|
||||||
try cases.append(else_prong);
|
try cases.append(t.gpa, else_prong);
|
||||||
}
|
}
|
||||||
|
|
||||||
const switch_node = try ZigTag.@"switch".create(t.arena, .{
|
const switch_node = try ZigTag.@"switch".create(t.arena, .{
|
||||||
@ -1861,7 +1862,7 @@ fn transCaseStmt(
|
|||||||
t: *Translator,
|
t: *Translator,
|
||||||
scope: *Scope,
|
scope: *Scope,
|
||||||
stmt: Node.Index,
|
stmt: Node.Index,
|
||||||
items: *std.array_list.Managed(ZigNode),
|
items: *std.ArrayList(ZigNode),
|
||||||
) TransError!Node.Index {
|
) TransError!Node.Index {
|
||||||
var sub = stmt;
|
var sub = stmt;
|
||||||
var seen_default = false;
|
var seen_default = false;
|
||||||
@ -1886,7 +1887,7 @@ fn transCaseStmt(
|
|||||||
break :blk try ZigTag.ellipsis3.create(t.arena, .{ .lhs = start_node, .rhs = end_node });
|
break :blk try ZigTag.ellipsis3.create(t.arena, .{ .lhs = start_node, .rhs = end_node });
|
||||||
} else try t.transExpr(scope, case_stmt.start, .used);
|
} else try t.transExpr(scope, case_stmt.start, .used);
|
||||||
|
|
||||||
try items.append(expr);
|
try items.append(t.gpa, expr);
|
||||||
sub = case_stmt.body;
|
sub = case_stmt.body;
|
||||||
},
|
},
|
||||||
else => return sub,
|
else => return sub,
|
||||||
@ -3873,7 +3874,7 @@ fn createNumberNode(t: *Translator, num: anytype, num_kind: enum { int, float })
|
|||||||
|
|
||||||
fn createCharLiteralNode(t: *Translator, narrow: bool, val: u32) TransError!ZigNode {
|
fn createCharLiteralNode(t: *Translator, narrow: bool, val: u32) TransError!ZigNode {
|
||||||
return ZigTag.char_literal.create(t.arena, if (narrow)
|
return ZigTag.char_literal.create(t.arena, if (narrow)
|
||||||
try std.fmt.allocPrint(t.arena, "'{f}'", .{std.zig.fmtChar(@intCast(val))})
|
try std.fmt.allocPrint(t.arena, "'{f}'", .{std.zig.fmtChar(@as(u8, @intCast(val)))})
|
||||||
else
|
else
|
||||||
try std.fmt.allocPrint(t.arena, "'\\u{{{x}}}'", .{val}));
|
try std.fmt.allocPrint(t.arena, "'\\u{{{x}}}'", .{val}));
|
||||||
}
|
}
|
||||||
@ -3986,8 +3987,8 @@ fn createFlexibleMemberFn(
|
|||||||
// =================
|
// =================
|
||||||
|
|
||||||
fn transMacros(t: *Translator) !void {
|
fn transMacros(t: *Translator) !void {
|
||||||
var tok_list = std.array_list.Managed(CToken).init(t.gpa);
|
var tok_list: std.ArrayList(CToken) = .empty;
|
||||||
defer tok_list.deinit();
|
defer tok_list.deinit(t.gpa);
|
||||||
|
|
||||||
var pattern_list = try PatternList.init(t.gpa);
|
var pattern_list = try PatternList.init(t.gpa);
|
||||||
defer pattern_list.deinit(t.gpa);
|
defer pattern_list.deinit(t.gpa);
|
||||||
@ -3999,7 +4000,7 @@ fn transMacros(t: *Translator) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tok_list.items.len = 0;
|
tok_list.items.len = 0;
|
||||||
try tok_list.ensureUnusedCapacity(macro.tokens.len);
|
try tok_list.ensureUnusedCapacity(t.gpa, macro.tokens.len);
|
||||||
for (macro.tokens) |tok| {
|
for (macro.tokens) |tok| {
|
||||||
switch (tok.id) {
|
switch (tok.id) {
|
||||||
.invalid => continue,
|
.invalid => continue,
|
||||||
|
|||||||
@ -798,9 +798,8 @@ pub const Payload = struct {
|
|||||||
pub fn render(gpa: Allocator, nodes: []const Node) !std.zig.Ast {
|
pub fn render(gpa: Allocator, nodes: []const Node) !std.zig.Ast {
|
||||||
var ctx: Context = .{
|
var ctx: Context = .{
|
||||||
.gpa = gpa,
|
.gpa = gpa,
|
||||||
.buf = std.array_list.Managed(u8).init(gpa),
|
|
||||||
};
|
};
|
||||||
defer ctx.buf.deinit();
|
defer ctx.buf.deinit(gpa);
|
||||||
defer ctx.nodes.deinit(gpa);
|
defer ctx.nodes.deinit(gpa);
|
||||||
defer ctx.extra_data.deinit(gpa);
|
defer ctx.extra_data.deinit(gpa);
|
||||||
defer ctx.tokens.deinit(gpa);
|
defer ctx.tokens.deinit(gpa);
|
||||||
@ -813,7 +812,7 @@ pub fn render(gpa: Allocator, nodes: []const Node) !std.zig.Ast {
|
|||||||
try ctx.tokens.ensureTotalCapacity(gpa, estimated_tokens_count);
|
try ctx.tokens.ensureTotalCapacity(gpa, estimated_tokens_count);
|
||||||
// Estimate that each each token is 3 bytes long.
|
// Estimate that each each token is 3 bytes long.
|
||||||
const estimated_buf_len = estimated_tokens_count * 3;
|
const estimated_buf_len = estimated_tokens_count * 3;
|
||||||
try ctx.buf.ensureTotalCapacity(estimated_buf_len);
|
try ctx.buf.ensureTotalCapacity(gpa, estimated_buf_len);
|
||||||
|
|
||||||
ctx.nodes.appendAssumeCapacity(.{
|
ctx.nodes.appendAssumeCapacity(.{
|
||||||
.tag = .root,
|
.tag = .root,
|
||||||
@ -822,12 +821,12 @@ pub fn render(gpa: Allocator, nodes: []const Node) !std.zig.Ast {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const root_members = blk: {
|
const root_members = blk: {
|
||||||
var result = std.array_list.Managed(NodeIndex).init(gpa);
|
var result: std.ArrayList(NodeIndex) = .empty;
|
||||||
defer result.deinit();
|
defer result.deinit(gpa);
|
||||||
|
|
||||||
for (nodes) |node| {
|
for (nodes) |node| {
|
||||||
const res = (try renderNodeOpt(&ctx, node)) orelse continue;
|
const res = (try renderNodeOpt(&ctx, node)) orelse continue;
|
||||||
try result.append(res);
|
try result.append(gpa, res);
|
||||||
}
|
}
|
||||||
break :blk try ctx.listToSpan(result.items);
|
break :blk try ctx.listToSpan(result.items);
|
||||||
};
|
};
|
||||||
@ -843,7 +842,7 @@ pub fn render(gpa: Allocator, nodes: []const Node) !std.zig.Ast {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
.source = try ctx.buf.toOwnedSliceSentinel(0),
|
.source = try ctx.buf.toOwnedSliceSentinel(gpa, 0),
|
||||||
.tokens = ctx.tokens.toOwnedSlice(),
|
.tokens = ctx.tokens.toOwnedSlice(),
|
||||||
.nodes = ctx.nodes.toOwnedSlice(),
|
.nodes = ctx.nodes.toOwnedSlice(),
|
||||||
.extra_data = try ctx.extra_data.toOwnedSlice(gpa),
|
.extra_data = try ctx.extra_data.toOwnedSlice(gpa),
|
||||||
@ -859,14 +858,14 @@ const TokenTag = std.zig.Token.Tag;
|
|||||||
|
|
||||||
const Context = struct {
|
const Context = struct {
|
||||||
gpa: Allocator,
|
gpa: Allocator,
|
||||||
buf: std.array_list.Managed(u8),
|
buf: std.ArrayList(u8) = .empty,
|
||||||
nodes: std.zig.Ast.NodeList = .{},
|
nodes: std.zig.Ast.NodeList = .empty,
|
||||||
extra_data: std.ArrayListUnmanaged(u32) = .empty,
|
extra_data: std.ArrayListUnmanaged(u32) = .empty,
|
||||||
tokens: std.zig.Ast.TokenList = .{},
|
tokens: std.zig.Ast.TokenList = .empty,
|
||||||
|
|
||||||
fn addTokenFmt(c: *Context, tag: TokenTag, comptime format: []const u8, args: anytype) Allocator.Error!TokenIndex {
|
fn addTokenFmt(c: *Context, tag: TokenTag, comptime format: []const u8, args: anytype) Allocator.Error!TokenIndex {
|
||||||
const start_index = c.buf.items.len;
|
const start_index = c.buf.items.len;
|
||||||
try c.buf.print(format ++ " ", args);
|
try c.buf.print(c.gpa, format ++ " ", args);
|
||||||
|
|
||||||
try c.tokens.append(c.gpa, .{
|
try c.tokens.append(c.gpa, .{
|
||||||
.tag = tag,
|
.tag = tag,
|
||||||
@ -925,8 +924,8 @@ fn renderNodeOpt(c: *Context, node: Node) Allocator.Error!?NodeIndex {
|
|||||||
switch (node.tag()) {
|
switch (node.tag()) {
|
||||||
.warning => {
|
.warning => {
|
||||||
const payload = node.castTag(.warning).?.data;
|
const payload = node.castTag(.warning).?.data;
|
||||||
try c.buf.appendSlice(payload);
|
try c.buf.appendSlice(c.gpa, payload);
|
||||||
try c.buf.append('\n');
|
try c.buf.append(c.gpa, '\n');
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
.discard => {
|
.discard => {
|
||||||
@ -1687,12 +1686,12 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
|
|||||||
}
|
}
|
||||||
const l_brace = try c.addToken(.l_brace, "{");
|
const l_brace = try c.addToken(.l_brace, "{");
|
||||||
|
|
||||||
var stmts = std.array_list.Managed(NodeIndex).init(c.gpa);
|
var stmts: std.ArrayList(NodeIndex) = .empty;
|
||||||
defer stmts.deinit();
|
defer stmts.deinit(c.gpa);
|
||||||
for (payload.stmts) |stmt| {
|
for (payload.stmts) |stmt| {
|
||||||
const res = (try renderNodeOpt(c, stmt)) orelse continue;
|
const res = (try renderNodeOpt(c, stmt)) orelse continue;
|
||||||
try addSemicolonIfNeeded(c, stmt);
|
try addSemicolonIfNeeded(c, stmt);
|
||||||
try stmts.append(res);
|
try stmts.append(c.gpa, res);
|
||||||
}
|
}
|
||||||
const span = try c.listToSpan(stmts.items);
|
const span = try c.listToSpan(stmts.items);
|
||||||
_ = try c.addToken(.r_brace, "}");
|
_ = try c.addToken(.r_brace, "}");
|
||||||
@ -2830,8 +2829,8 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {
|
|||||||
const fn_token = try c.addToken(.keyword_fn, "fn");
|
const fn_token = try c.addToken(.keyword_fn, "fn");
|
||||||
if (payload.name) |some| _ = try c.addIdentifier(some);
|
if (payload.name) |some| _ = try c.addIdentifier(some);
|
||||||
|
|
||||||
const params = try renderParams(c, payload.params, payload.is_var_args);
|
var params = try renderParams(c, payload.params, payload.is_var_args);
|
||||||
defer params.deinit();
|
defer params.deinit(c.gpa);
|
||||||
var span: NodeSubRange = undefined;
|
var span: NodeSubRange = undefined;
|
||||||
if (params.items.len > 1) span = try c.listToSpan(params.items);
|
if (params.items.len > 1) span = try c.listToSpan(params.items);
|
||||||
|
|
||||||
@ -2998,8 +2997,8 @@ fn renderMacroFunc(c: *Context, node: Node) !NodeIndex {
|
|||||||
const fn_token = try c.addToken(.keyword_fn, "fn");
|
const fn_token = try c.addToken(.keyword_fn, "fn");
|
||||||
_ = try c.addIdentifier(payload.name);
|
_ = try c.addIdentifier(payload.name);
|
||||||
|
|
||||||
const params = try renderParams(c, payload.params, false);
|
var params = try renderParams(c, payload.params, false);
|
||||||
defer params.deinit();
|
defer params.deinit(c.gpa);
|
||||||
var span: NodeSubRange = undefined;
|
var span: NodeSubRange = undefined;
|
||||||
if (params.items.len > 1) span = try c.listToSpan(params.items);
|
if (params.items.len > 1) span = try c.listToSpan(params.items);
|
||||||
|
|
||||||
@ -3035,10 +3034,11 @@ fn renderMacroFunc(c: *Context, node: Node) !NodeIndex {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn renderParams(c: *Context, params: []Payload.Param, is_var_args: bool) !std.array_list.Managed(NodeIndex) {
|
fn renderParams(c: *Context, params: []Payload.Param, is_var_args: bool) !std.ArrayList(NodeIndex) {
|
||||||
_ = try c.addToken(.l_paren, "(");
|
_ = try c.addToken(.l_paren, "(");
|
||||||
var rendered = try std.array_list.Managed(NodeIndex).initCapacity(c.gpa, @max(params.len, 1));
|
var rendered: std.ArrayList(NodeIndex) = .empty;
|
||||||
errdefer rendered.deinit();
|
errdefer rendered.deinit(c.gpa);
|
||||||
|
try rendered.ensureUnusedCapacity(c.gpa, @max(params.len, 1));
|
||||||
|
|
||||||
for (params, 0..) |param, i| {
|
for (params, 0..) |param, i| {
|
||||||
if (i != 0) _ = try c.addToken(.comma, ",");
|
if (i != 0) _ = try c.addToken(.comma, ",");
|
||||||
|
|||||||
@ -110,7 +110,7 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8) !void {
|
|||||||
defer macro_buf.deinit(gpa);
|
defer macro_buf.deinit(gpa);
|
||||||
|
|
||||||
var discard_buf: [256]u8 = undefined;
|
var discard_buf: [256]u8 = undefined;
|
||||||
var discarding: std.io.Writer.Discarding = .init(&discard_buf);
|
var discarding: std.Io.Writer.Discarding = .init(&discard_buf);
|
||||||
assert(!try d.parseArgs(&discarding.writer, ¯o_buf, aro_args));
|
assert(!try d.parseArgs(&discarding.writer, ¯o_buf, aro_args));
|
||||||
if (macro_buf.items.len > std.math.maxInt(u32)) {
|
if (macro_buf.items.len > std.math.maxInt(u32)) {
|
||||||
return d.fatal("user provided macro source exceeded max size", .{});
|
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 {
|
|||||||
out_file_path = path;
|
out_file_path = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
var out_writer = out_file.writer(&.{});
|
var out_writer = out_file.writer(&out_buf);
|
||||||
out_writer.interface.writeAll(rendered_zig) catch
|
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.?) });
|
out_writer.interface.flush() catch {};
|
||||||
|
if (out_writer.err) |write_err|
|
||||||
|
return d.fatal("failed to write result to '{s}': {s}", .{ out_file_path, aro.Driver.errorDescription(write_err) });
|
||||||
|
|
||||||
if (fast_exit) process.exit(0);
|
if (fast_exit) process.exit(0);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user