mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-09-01 21:33:54 -06:00
CLI: use zon format for clang options
- plain old data ftw - 177K -> 151K - data bypasses Sema This change is not really important but it was nice to explore best practices for data like this. When I measured building the compiler, I found no statistically significant difference in compilation time.
This commit is contained in:
parent
982f26bcdd
commit
06b85a4fd0
@ -348,8 +348,6 @@ set(ZIG_STAGE2_SOURCES
|
||||
src/Value.zig
|
||||
src/Zcu.zig
|
||||
src/Zcu/PerThread.zig
|
||||
src/clang_options.zig
|
||||
src/clang_options_data.zig
|
||||
src/codegen.zig
|
||||
src/codegen/aarch64.zig
|
||||
src/codegen/aarch64/abi.zig
|
||||
|
||||
182
lib/std/zig.zig
182
lib/std/zig.zig
@ -3,12 +3,14 @@
|
||||
//! guarantees whatsoever.
|
||||
|
||||
const std = @import("std.zig");
|
||||
const tokenizer = @import("zig/tokenizer.zig");
|
||||
const assert = std.debug.assert;
|
||||
const mem = std.mem;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const Io = std.Io;
|
||||
const Writer = std.Io.Writer;
|
||||
|
||||
const tokenizer = @import("zig/tokenizer.zig");
|
||||
|
||||
pub const ErrorBundle = @import("zig/ErrorBundle.zig");
|
||||
pub const Server = @import("zig/Server.zig");
|
||||
pub const Client = @import("zig/Client.zig");
|
||||
@ -94,7 +96,7 @@ pub const Loc = struct {
|
||||
source_line: []const u8,
|
||||
|
||||
pub fn eql(a: Loc, b: Loc) bool {
|
||||
return a.line == b.line and a.column == b.column and std.mem.eql(u8, a.source_line, b.source_line);
|
||||
return a.line == b.line and a.column == b.column and mem.eql(u8, a.source_line, b.source_line);
|
||||
}
|
||||
};
|
||||
|
||||
@ -258,7 +260,7 @@ pub const BuildId = union(enum) {
|
||||
if (a_tag != b_tag) return false;
|
||||
return switch (a) {
|
||||
.none, .fast, .uuid, .sha1, .md5 => true,
|
||||
.hexstring => |a_hexstring| std.mem.eql(u8, a_hexstring.toSlice(), b.hexstring.toSlice()),
|
||||
.hexstring => |a_hexstring| mem.eql(u8, a_hexstring.toSlice(), b.hexstring.toSlice()),
|
||||
};
|
||||
}
|
||||
|
||||
@ -285,17 +287,17 @@ pub const BuildId = union(enum) {
|
||||
|
||||
/// Converts UTF-8 text to a `BuildId`.
|
||||
pub fn parse(text: []const u8) !BuildId {
|
||||
if (std.mem.eql(u8, text, "none")) {
|
||||
if (mem.eql(u8, text, "none")) {
|
||||
return .none;
|
||||
} else if (std.mem.eql(u8, text, "fast")) {
|
||||
} else if (mem.eql(u8, text, "fast")) {
|
||||
return .fast;
|
||||
} else if (std.mem.eql(u8, text, "uuid")) {
|
||||
} else if (mem.eql(u8, text, "uuid")) {
|
||||
return .uuid;
|
||||
} else if (std.mem.eql(u8, text, "sha1") or std.mem.eql(u8, text, "tree")) {
|
||||
} else if (mem.eql(u8, text, "sha1") or mem.eql(u8, text, "tree")) {
|
||||
return .sha1;
|
||||
} else if (std.mem.eql(u8, text, "md5")) {
|
||||
} else if (mem.eql(u8, text, "md5")) {
|
||||
return .md5;
|
||||
} else if (std.mem.startsWith(u8, text, "0x")) {
|
||||
} else if (mem.startsWith(u8, text, "0x")) {
|
||||
var result: BuildId = .{ .hexstring = undefined };
|
||||
const slice = try std.fmt.hexToBytes(&result.hexstring.bytes, text[2..]);
|
||||
result.hexstring.len = @as(u8, @intCast(slice.len));
|
||||
@ -614,13 +616,13 @@ pub fn readSourceFileToEndAlloc(gpa: Allocator, file_reader: *Io.File.Reader) ![
|
||||
"\xfe\xff", // UTF-16 big endian
|
||||
};
|
||||
for (unsupported_boms) |bom| {
|
||||
if (std.mem.startsWith(u8, buffer.items, bom)) {
|
||||
if (mem.startsWith(u8, buffer.items, bom)) {
|
||||
return error.UnsupportedEncoding;
|
||||
}
|
||||
}
|
||||
|
||||
// If the file starts with a UTF-16 little endian BOM, translate it to UTF-8
|
||||
if (std.mem.startsWith(u8, buffer.items, "\xff\xfe")) {
|
||||
if (mem.startsWith(u8, buffer.items, "\xff\xfe")) {
|
||||
if (buffer.items.len % 2 != 0) return error.InvalidEncoding;
|
||||
return std.unicode.utf16LeToUtf8AllocZ(gpa, @ptrCast(@alignCast(buffer.items))) catch |err| switch (err) {
|
||||
error.DanglingSurrogateHalf => error.UnsupportedEncoding,
|
||||
@ -1002,6 +1004,164 @@ pub const EmitArtifact = enum {
|
||||
}
|
||||
};
|
||||
|
||||
/// The defaults are chosen here to reduce the size of src/clang_options.zon
|
||||
pub const ClangCliParam = struct {
|
||||
name: []const u8,
|
||||
ze: ZigEquivalent = .other,
|
||||
syntax: Syntax = .flag,
|
||||
/// Prefixed by "-"
|
||||
pd1: bool = true,
|
||||
/// Prefixed by "--"
|
||||
pd2: bool = false,
|
||||
/// Prefixed by "/"
|
||||
psl: bool = false,
|
||||
|
||||
pub const Syntax = union(enum) {
|
||||
/// A flag with no values.
|
||||
flag,
|
||||
/// An option which prefixes its (single) value.
|
||||
joined,
|
||||
/// An option which is followed by its value.
|
||||
separate,
|
||||
/// An option which is either joined to its (non-empty) value, or followed by its value.
|
||||
joined_or_separate,
|
||||
/// An option which is both joined to its (first) value, and followed by its (second) value.
|
||||
joined_and_separate,
|
||||
/// An option followed by its values, which are separated by commas.
|
||||
comma_joined,
|
||||
/// An option which consumes an optional joined argument and any other remaining arguments.
|
||||
remaining_args_joined,
|
||||
/// An option which is which takes multiple (separate) arguments.
|
||||
multi_arg: u8,
|
||||
};
|
||||
|
||||
pub const ZigEquivalent = enum {
|
||||
target,
|
||||
o,
|
||||
c,
|
||||
r,
|
||||
m,
|
||||
x,
|
||||
other,
|
||||
positional,
|
||||
l,
|
||||
ignore,
|
||||
driver_punt,
|
||||
pic,
|
||||
no_pic,
|
||||
pie,
|
||||
no_pie,
|
||||
lto,
|
||||
no_lto,
|
||||
unwind_tables,
|
||||
no_unwind_tables,
|
||||
asynchronous_unwind_tables,
|
||||
no_asynchronous_unwind_tables,
|
||||
nostdlib,
|
||||
nostdlib_cpp,
|
||||
shared,
|
||||
rdynamic,
|
||||
wl,
|
||||
wp,
|
||||
preprocess_only,
|
||||
asm_only,
|
||||
optimize,
|
||||
debug,
|
||||
gdwarf32,
|
||||
gdwarf64,
|
||||
sanitize,
|
||||
no_sanitize,
|
||||
sanitize_trap,
|
||||
no_sanitize_trap,
|
||||
linker_script,
|
||||
dry_run,
|
||||
verbose,
|
||||
for_linker,
|
||||
linker_input_z,
|
||||
lib_dir,
|
||||
mcpu,
|
||||
dep_file,
|
||||
dep_file_to_stdout,
|
||||
framework_dir,
|
||||
framework,
|
||||
nostdlibinc,
|
||||
red_zone,
|
||||
no_red_zone,
|
||||
omit_frame_pointer,
|
||||
no_omit_frame_pointer,
|
||||
function_sections,
|
||||
no_function_sections,
|
||||
data_sections,
|
||||
no_data_sections,
|
||||
builtin,
|
||||
no_builtin,
|
||||
color_diagnostics,
|
||||
no_color_diagnostics,
|
||||
stack_check,
|
||||
no_stack_check,
|
||||
stack_protector,
|
||||
no_stack_protector,
|
||||
strip,
|
||||
exec_model,
|
||||
emit_llvm,
|
||||
sysroot,
|
||||
entry,
|
||||
force_undefined_symbol,
|
||||
weak_library,
|
||||
weak_framework,
|
||||
headerpad_max_install_names,
|
||||
compress_debug_sections,
|
||||
install_name,
|
||||
undefined,
|
||||
force_load_objc,
|
||||
mingw_unicode_entry_point,
|
||||
san_cov_trace_pc_guard,
|
||||
san_cov,
|
||||
no_san_cov,
|
||||
rtlib,
|
||||
static,
|
||||
dynamic,
|
||||
};
|
||||
|
||||
pub fn matchEql(self: @This(), arg: []const u8) u2 {
|
||||
if (self.pd1 and arg.len >= self.name.len + 1 and
|
||||
mem.startsWith(u8, arg, "-") and mem.eql(u8, arg[1..], self.name))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (self.pd2 and arg.len >= self.name.len + 2 and
|
||||
mem.startsWith(u8, arg, "--") and mem.eql(u8, arg[2..], self.name))
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
if (self.psl and arg.len >= self.name.len + 1 and
|
||||
mem.startsWith(u8, arg, "/") and mem.eql(u8, arg[1..], self.name))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
pub fn matchStartsWith(self: @This(), arg: []const u8) usize {
|
||||
if (self.pd1 and arg.len >= self.name.len + 1 and
|
||||
mem.startsWith(u8, arg, "-") and mem.startsWith(u8, arg[1..], self.name))
|
||||
{
|
||||
return self.name.len + 1;
|
||||
}
|
||||
if (self.pd2 and arg.len >= self.name.len + 2 and
|
||||
mem.startsWith(u8, arg, "--") and mem.startsWith(u8, arg[2..], self.name))
|
||||
{
|
||||
return self.name.len + 2;
|
||||
}
|
||||
if (self.psl and arg.len >= self.name.len + 1 and
|
||||
mem.startsWith(u8, arg, "/") and mem.startsWith(u8, arg[1..], self.name))
|
||||
{
|
||||
return self.name.len + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
test {
|
||||
_ = Ast;
|
||||
_ = AstRlAnnotate;
|
||||
|
||||
@ -1,144 +0,0 @@
|
||||
const std = @import("std");
|
||||
const mem = std.mem;
|
||||
|
||||
pub const list = @import("clang_options_data.zig").data;
|
||||
|
||||
pub const CliArg = struct {
|
||||
name: []const u8,
|
||||
syntax: Syntax,
|
||||
|
||||
zig_equivalent: @import("main.zig").ClangArgIterator.ZigEquivalent,
|
||||
|
||||
/// Prefixed by "-"
|
||||
pd1: bool = false,
|
||||
|
||||
/// Prefixed by "--"
|
||||
pd2: bool = false,
|
||||
|
||||
/// Prefixed by "/"
|
||||
psl: bool = false,
|
||||
|
||||
pub const Syntax = union(enum) {
|
||||
/// A flag with no values.
|
||||
flag,
|
||||
|
||||
/// An option which prefixes its (single) value.
|
||||
joined,
|
||||
|
||||
/// An option which is followed by its value.
|
||||
separate,
|
||||
|
||||
/// An option which is either joined to its (non-empty) value, or followed by its value.
|
||||
joined_or_separate,
|
||||
|
||||
/// An option which is both joined to its (first) value, and followed by its (second) value.
|
||||
joined_and_separate,
|
||||
|
||||
/// An option followed by its values, which are separated by commas.
|
||||
comma_joined,
|
||||
|
||||
/// An option which consumes an optional joined argument and any other remaining arguments.
|
||||
remaining_args_joined,
|
||||
|
||||
/// An option which is which takes multiple (separate) arguments.
|
||||
multi_arg: u8,
|
||||
};
|
||||
|
||||
pub fn matchEql(self: CliArg, arg: []const u8) u2 {
|
||||
if (self.pd1 and arg.len >= self.name.len + 1 and
|
||||
mem.startsWith(u8, arg, "-") and mem.eql(u8, arg[1..], self.name))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (self.pd2 and arg.len >= self.name.len + 2 and
|
||||
mem.startsWith(u8, arg, "--") and mem.eql(u8, arg[2..], self.name))
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
if (self.psl and arg.len >= self.name.len + 1 and
|
||||
mem.startsWith(u8, arg, "/") and mem.eql(u8, arg[1..], self.name))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
pub fn matchStartsWith(self: CliArg, arg: []const u8) usize {
|
||||
if (self.pd1 and arg.len >= self.name.len + 1 and
|
||||
mem.startsWith(u8, arg, "-") and mem.startsWith(u8, arg[1..], self.name))
|
||||
{
|
||||
return self.name.len + 1;
|
||||
}
|
||||
if (self.pd2 and arg.len >= self.name.len + 2 and
|
||||
mem.startsWith(u8, arg, "--") and mem.startsWith(u8, arg[2..], self.name))
|
||||
{
|
||||
return self.name.len + 2;
|
||||
}
|
||||
if (self.psl and arg.len >= self.name.len + 1 and
|
||||
mem.startsWith(u8, arg, "/") and mem.startsWith(u8, arg[1..], self.name))
|
||||
{
|
||||
return self.name.len + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
/// Shortcut function for initializing a `CliArg`
|
||||
pub fn flagpd1(name: []const u8) CliArg {
|
||||
return .{
|
||||
.name = name,
|
||||
.syntax = .flag,
|
||||
.zig_equivalent = .other,
|
||||
.pd1 = true,
|
||||
};
|
||||
}
|
||||
|
||||
/// Shortcut function for initializing a `CliArg`
|
||||
pub fn flagpsl(name: []const u8) CliArg {
|
||||
return .{
|
||||
.name = name,
|
||||
.syntax = .flag,
|
||||
.zig_equivalent = .other,
|
||||
.psl = true,
|
||||
};
|
||||
}
|
||||
|
||||
/// Shortcut function for initializing a `CliArg`
|
||||
pub fn joinpd1(name: []const u8) CliArg {
|
||||
return .{
|
||||
.name = name,
|
||||
.syntax = .joined,
|
||||
.zig_equivalent = .other,
|
||||
.pd1 = true,
|
||||
};
|
||||
}
|
||||
|
||||
/// Shortcut function for initializing a `CliArg`
|
||||
pub fn jspd1(name: []const u8) CliArg {
|
||||
return .{
|
||||
.name = name,
|
||||
.syntax = .joined_or_separate,
|
||||
.zig_equivalent = .other,
|
||||
.pd1 = true,
|
||||
};
|
||||
}
|
||||
|
||||
/// Shortcut function for initializing a `CliArg`
|
||||
pub fn sepd1(name: []const u8) CliArg {
|
||||
return .{
|
||||
.name = name,
|
||||
.syntax = .separate,
|
||||
.zig_equivalent = .other,
|
||||
.pd1 = true,
|
||||
};
|
||||
}
|
||||
|
||||
/// Shortcut function for initializing a `CliArg`
|
||||
pub fn m(name: []const u8) CliArg {
|
||||
return .{
|
||||
.name = name,
|
||||
.syntax = .flag,
|
||||
.zig_equivalent = .m,
|
||||
.pd1 = true,
|
||||
};
|
||||
}
|
||||
5060
src/clang_options.zon
Normal file
5060
src/clang_options.zon
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
108
src/main.zig
108
src/main.zig
@ -6042,11 +6042,9 @@ fn initArgIteratorResponseFile(allocator: Allocator, io: Io, resp_file_path: []c
|
||||
return ArgIteratorResponseFile.initTakeOwnership(allocator, cmd_line);
|
||||
}
|
||||
|
||||
const clang_args = @import("clang_options.zig").list;
|
||||
|
||||
pub const ClangArgIterator = struct {
|
||||
has_next: bool,
|
||||
zig_equivalent: ZigEquivalent,
|
||||
zig_equivalent: std.zig.ClangCliParam.ZigEquivalent,
|
||||
only_arg: []const u8,
|
||||
second_arg: []const u8,
|
||||
other_args: []const []const u8,
|
||||
@ -6056,94 +6054,6 @@ pub const ClangArgIterator = struct {
|
||||
arg_iterator_response_file: ArgIteratorResponseFile,
|
||||
arena: Allocator,
|
||||
|
||||
pub const ZigEquivalent = enum {
|
||||
target,
|
||||
o,
|
||||
c,
|
||||
r,
|
||||
m,
|
||||
x,
|
||||
other,
|
||||
positional,
|
||||
l,
|
||||
ignore,
|
||||
driver_punt,
|
||||
pic,
|
||||
no_pic,
|
||||
pie,
|
||||
no_pie,
|
||||
lto,
|
||||
no_lto,
|
||||
unwind_tables,
|
||||
no_unwind_tables,
|
||||
asynchronous_unwind_tables,
|
||||
no_asynchronous_unwind_tables,
|
||||
nostdlib,
|
||||
nostdlib_cpp,
|
||||
shared,
|
||||
rdynamic,
|
||||
wl,
|
||||
wp,
|
||||
preprocess_only,
|
||||
asm_only,
|
||||
optimize,
|
||||
debug,
|
||||
gdwarf32,
|
||||
gdwarf64,
|
||||
sanitize,
|
||||
no_sanitize,
|
||||
sanitize_trap,
|
||||
no_sanitize_trap,
|
||||
linker_script,
|
||||
dry_run,
|
||||
verbose,
|
||||
for_linker,
|
||||
linker_input_z,
|
||||
lib_dir,
|
||||
mcpu,
|
||||
dep_file,
|
||||
dep_file_to_stdout,
|
||||
framework_dir,
|
||||
framework,
|
||||
nostdlibinc,
|
||||
red_zone,
|
||||
no_red_zone,
|
||||
omit_frame_pointer,
|
||||
no_omit_frame_pointer,
|
||||
function_sections,
|
||||
no_function_sections,
|
||||
data_sections,
|
||||
no_data_sections,
|
||||
builtin,
|
||||
no_builtin,
|
||||
color_diagnostics,
|
||||
no_color_diagnostics,
|
||||
stack_check,
|
||||
no_stack_check,
|
||||
stack_protector,
|
||||
no_stack_protector,
|
||||
strip,
|
||||
exec_model,
|
||||
emit_llvm,
|
||||
sysroot,
|
||||
entry,
|
||||
force_undefined_symbol,
|
||||
weak_library,
|
||||
weak_framework,
|
||||
headerpad_max_install_names,
|
||||
compress_debug_sections,
|
||||
install_name,
|
||||
undefined,
|
||||
force_load_objc,
|
||||
mingw_unicode_entry_point,
|
||||
san_cov_trace_pc_guard,
|
||||
san_cov,
|
||||
no_san_cov,
|
||||
rtlib,
|
||||
static,
|
||||
dynamic,
|
||||
};
|
||||
|
||||
const Args = struct {
|
||||
next_index: usize,
|
||||
argv: []const []const u8,
|
||||
@ -6223,11 +6133,13 @@ pub const ClangArgIterator = struct {
|
||||
return;
|
||||
}
|
||||
|
||||
const clang_args: []const std.zig.ClangCliParam = @import("clang_options.zon");
|
||||
|
||||
find_clang_arg: for (clang_args) |clang_arg| switch (clang_arg.syntax) {
|
||||
.flag => {
|
||||
const prefix_len = clang_arg.matchEql(arg);
|
||||
if (prefix_len > 0) {
|
||||
self.zig_equivalent = clang_arg.zig_equivalent;
|
||||
self.zig_equivalent = clang_arg.ze;
|
||||
self.only_arg = arg[prefix_len..];
|
||||
|
||||
break :find_clang_arg;
|
||||
@ -6238,7 +6150,7 @@ pub const ClangArgIterator = struct {
|
||||
// comma_joined example: -Wl,-soname,libsoundio.so.2
|
||||
const prefix_len = clang_arg.matchStartsWith(arg);
|
||||
if (prefix_len != 0) {
|
||||
self.zig_equivalent = clang_arg.zig_equivalent;
|
||||
self.zig_equivalent = clang_arg.ze;
|
||||
self.only_arg = arg[prefix_len..]; // This will skip over the "--target=" part.
|
||||
|
||||
break :find_clang_arg;
|
||||
@ -6254,11 +6166,11 @@ pub const ClangArgIterator = struct {
|
||||
self.only_arg = self.argv[self.next_index];
|
||||
self.incrementArgIndex();
|
||||
self.other_args.len += 1;
|
||||
self.zig_equivalent = clang_arg.zig_equivalent;
|
||||
self.zig_equivalent = clang_arg.ze;
|
||||
|
||||
break :find_clang_arg;
|
||||
} else if (prefix_len != 0) {
|
||||
self.zig_equivalent = clang_arg.zig_equivalent;
|
||||
self.zig_equivalent = clang_arg.ze;
|
||||
self.only_arg = arg[prefix_len..];
|
||||
|
||||
break :find_clang_arg;
|
||||
@ -6275,7 +6187,7 @@ pub const ClangArgIterator = struct {
|
||||
self.second_arg = self.argv[self.next_index];
|
||||
self.incrementArgIndex();
|
||||
self.other_args.len += 1;
|
||||
self.zig_equivalent = clang_arg.zig_equivalent;
|
||||
self.zig_equivalent = clang_arg.ze;
|
||||
break :find_clang_arg;
|
||||
}
|
||||
},
|
||||
@ -6286,7 +6198,7 @@ pub const ClangArgIterator = struct {
|
||||
self.only_arg = self.argv[self.next_index];
|
||||
self.incrementArgIndex();
|
||||
self.other_args.len += 1;
|
||||
self.zig_equivalent = clang_arg.zig_equivalent;
|
||||
self.zig_equivalent = clang_arg.ze;
|
||||
break :find_clang_arg;
|
||||
},
|
||||
.remaining_args_joined => {
|
||||
@ -6302,7 +6214,7 @@ pub const ClangArgIterator = struct {
|
||||
self.incrementArgIndex();
|
||||
self.other_args.len += 1;
|
||||
}
|
||||
self.zig_equivalent = clang_arg.zig_equivalent;
|
||||
self.zig_equivalent = clang_arg.ze;
|
||||
break :find_clang_arg;
|
||||
},
|
||||
} else {
|
||||
|
||||
@ -13,6 +13,8 @@ const std = @import("std");
|
||||
const Io = std.Io;
|
||||
const assert = std.debug.assert;
|
||||
const json = std.json;
|
||||
const fatal = std.process.fatal;
|
||||
const ClangCliParam = std.zig.ClangCliParam;
|
||||
|
||||
const KnownOpt = struct {
|
||||
name: []const u8,
|
||||
@ -682,13 +684,9 @@ pub fn main(init: std.process.Init) !void {
|
||||
|
||||
const json_text = switch (child_result.term) {
|
||||
.exited => |code| if (code == 0) child_result.stdout else {
|
||||
std.debug.print("llvm-tblgen exited with code {d}\n", .{code});
|
||||
std.process.exit(1);
|
||||
},
|
||||
else => {
|
||||
std.debug.print("llvm-tblgen crashed\n", .{});
|
||||
std.process.exit(1);
|
||||
fatal("llvm-tblgen exited with code {d}", .{code});
|
||||
},
|
||||
else => fatal("llvm-tblgen crashed", .{}),
|
||||
};
|
||||
|
||||
const parsed = try json.parseFromSlice(json.Value, arena, json_text, .{});
|
||||
@ -718,18 +716,13 @@ pub fn main(init: std.process.Init) !void {
|
||||
try stdout.writeAll(
|
||||
\\// This file is generated by tools/update_clang_options.zig.
|
||||
\\// zig fmt: off
|
||||
\\const clang_options = @import("clang_options.zig");
|
||||
\\const CliArg = clang_options.CliArg;
|
||||
\\const flagpd1 = clang_options.flagpd1;
|
||||
\\const flagpsl = clang_options.flagpsl;
|
||||
\\const joinpd1 = clang_options.joinpd1;
|
||||
\\const jspd1 = clang_options.jspd1;
|
||||
\\const sepd1 = clang_options.sepd1;
|
||||
\\const m = clang_options.m;
|
||||
\\pub const data = blk: { @setEvalBranchQuota(6000); break :blk &[_]CliArg{
|
||||
\\
|
||||
);
|
||||
|
||||
var serializer: std.zon.Serializer = .{ .writer = stdout };
|
||||
var top = try serializer.beginTuple(.{});
|
||||
serializer.indent_level = 0;
|
||||
|
||||
for (all_objects.items) |obj| {
|
||||
const name = obj.get("Name").?.string;
|
||||
var pd1 = false;
|
||||
@ -744,113 +737,48 @@ pub fn main(init: std.process.Init) !void {
|
||||
} else if (std.mem.eql(u8, prefix, "/")) {
|
||||
pslash = true;
|
||||
} else {
|
||||
std.debug.print("{s} has unrecognized prefix '{s}'\n", .{ name, prefix });
|
||||
std.process.exit(1);
|
||||
fatal("{s} has unrecognized prefix '{s}'", .{ name, prefix });
|
||||
}
|
||||
}
|
||||
const syntax = objSyntax(obj) orelse continue;
|
||||
|
||||
var element: ClangCliParam = .{
|
||||
.name = name,
|
||||
.syntax = syntax,
|
||||
.pd1 = pd1,
|
||||
.pd2 = pd2,
|
||||
.psl = pslash,
|
||||
};
|
||||
|
||||
if (std.mem.eql(u8, name, "MT") and syntax == .flag) {
|
||||
// `-MT foo` is ambiguous because there is also an -MT flag
|
||||
// The canonical way to specify the flag is with `/MT` and so we make this
|
||||
// the only way.
|
||||
try stdout.print("flagpsl(\"{s}\"),\n", .{name});
|
||||
element.psl = true;
|
||||
element.pd1 = false;
|
||||
element.pd2 = false;
|
||||
} else if (knownOption(name)) |ident| {
|
||||
|
||||
// Workaround the fact that in 'Options.td' -Ofast is listed as 'joined'
|
||||
const final_syntax = if (std.mem.eql(u8, name, "Ofast")) .flag else syntax;
|
||||
|
||||
try stdout.print(
|
||||
\\.{{
|
||||
\\ .name = "{s}",
|
||||
\\ .syntax = {f},
|
||||
\\ .zig_equivalent = .{s},
|
||||
\\ .pd1 = {},
|
||||
\\ .pd2 = {},
|
||||
\\ .psl = {},
|
||||
\\}},
|
||||
\\
|
||||
, .{ name, final_syntax, ident, pd1, pd2, pslash });
|
||||
if (std.mem.eql(u8, name, "Ofast")) element.syntax = .flag;
|
||||
element.ze = std.meta.stringToEnum(ClangCliParam.ZigEquivalent, ident) orelse fatal("unknown known option: {s}", .{ident});
|
||||
} else if (pd1 and !pd2 and !pslash and syntax == .flag) {
|
||||
if ((std.mem.startsWith(u8, name, "mno-") and
|
||||
llvm_to_zig_cpu_features.contains(name["mno-".len..])) or
|
||||
(std.mem.startsWith(u8, name, "m") and
|
||||
llvm_to_zig_cpu_features.contains(name["m".len..])))
|
||||
{
|
||||
try stdout.print("m(\"{s}\"),\n", .{name});
|
||||
} else {
|
||||
try stdout.print("flagpd1(\"{s}\"),\n", .{name});
|
||||
element.ze = .m;
|
||||
}
|
||||
} else if (!pd1 and !pd2 and pslash and syntax == .flag) {
|
||||
try stdout.print("flagpsl(\"{s}\"),\n", .{name});
|
||||
} else if (pd1 and !pd2 and !pslash and syntax == .joined) {
|
||||
try stdout.print("joinpd1(\"{s}\"),\n", .{name});
|
||||
} else if (pd1 and !pd2 and !pslash and syntax == .joined_or_separate) {
|
||||
try stdout.print("jspd1(\"{s}\"),\n", .{name});
|
||||
} else if (pd1 and !pd2 and !pslash and syntax == .separate) {
|
||||
try stdout.print("sepd1(\"{s}\"),\n", .{name});
|
||||
} else {
|
||||
try stdout.print(
|
||||
\\.{{
|
||||
\\ .name = "{s}",
|
||||
\\ .syntax = {f},
|
||||
\\ .zig_equivalent = .other,
|
||||
\\ .pd1 = {},
|
||||
\\ .pd2 = {},
|
||||
\\ .psl = {},
|
||||
\\}},
|
||||
\\
|
||||
, .{ name, syntax, pd1, pd2, pslash });
|
||||
}
|
||||
try top.field(element, .{ .emit_default_optional_fields = false });
|
||||
}
|
||||
|
||||
try stdout.writeAll(
|
||||
\\};};
|
||||
\\
|
||||
);
|
||||
try top.end();
|
||||
|
||||
try stdout.flush();
|
||||
}
|
||||
|
||||
// TODO we should be able to import clang_options.zig but currently this is problematic because it will
|
||||
// import stage2.zig and that causes a bunch of stuff to get exported
|
||||
const Syntax = union(enum) {
|
||||
/// A flag with no values.
|
||||
flag,
|
||||
|
||||
/// An option which prefixes its (single) value.
|
||||
joined,
|
||||
|
||||
/// An option which is followed by its value.
|
||||
separate,
|
||||
|
||||
/// An option which is either joined to its (non-empty) value, or followed by its value.
|
||||
joined_or_separate,
|
||||
|
||||
/// An option which is both joined to its (first) value, and followed by its (second) value.
|
||||
joined_and_separate,
|
||||
|
||||
/// An option followed by its values, which are separated by commas.
|
||||
comma_joined,
|
||||
|
||||
/// An option which consumes an optional joined argument and any other remaining arguments.
|
||||
remaining_args_joined,
|
||||
|
||||
/// An option which is which takes multiple (separate) arguments.
|
||||
multi_arg: u8,
|
||||
|
||||
pub fn format(
|
||||
self: Syntax,
|
||||
out_stream: *std.Io.Writer,
|
||||
) std.Io.Writer.Error!void {
|
||||
switch (self) {
|
||||
.multi_arg => |n| return out_stream.print(".{{.{t}={d}}}", .{ self, n }),
|
||||
else => return out_stream.print(".{s}", .{@tagName(self)}),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
fn objSyntax(obj: *json.ObjectMap) ?Syntax {
|
||||
fn objSyntax(obj: *json.ObjectMap) ?ClangCliParam.Syntax {
|
||||
const num_args = @as(u8, @intCast(obj.get("NumArgs").?.integer));
|
||||
for (obj.get("!superclasses").?.array.items) |superclass_json| {
|
||||
const superclass = superclass_json.string;
|
||||
@ -911,7 +839,7 @@ fn objSyntax(obj: *json.ObjectMap) ?Syntax {
|
||||
return null;
|
||||
}
|
||||
|
||||
fn syntaxMatchesWithEql(syntax: Syntax) bool {
|
||||
fn syntaxMatchesWithEql(syntax: ClangCliParam.Syntax) bool {
|
||||
return switch (syntax) {
|
||||
.flag,
|
||||
.separate,
|
||||
@ -966,9 +894,8 @@ fn printUsageAndExit(arg0: []const u8) noreturn {
|
||||
fn printUsage(w: *std.Io.Writer, arg0: []const u8) std.Io.Writer.Error!void {
|
||||
try w.print(
|
||||
\\Usage: {s} /path/to/llvm-tblgen /path/to/git/llvm/llvm-project
|
||||
\\Alternative Usage: zig run /path/to/git/zig/tools/update_clang_options.zig -- /path/to/llvm-tblgen /path/to/git/llvm/llvm-project
|
||||
\\
|
||||
\\Prints to stdout Zig code which you can use to replace the file src/clang_options_data.zig.
|
||||
\\Prints to stdout Zig code which you can use to replace the file src/clang_options.zon.
|
||||
\\
|
||||
, .{arg0});
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user